use crate::objects::freq::Freq;
#[cfg(feature = "python")]
use chrono::{DateTime, Utc};
#[cfg(feature = "python")]
use pyo3::exceptions::PyValueError;
#[cfg(feature = "python")]
use pyo3::prelude::*;
#[cfg(feature = "python")]
use pyo3::types::PyAnyMethods;
#[cfg(feature = "python")]
pub fn create_ordered_dict(py: Python) -> PyResult<Py<PyAny>> {
let collections = py.import("collections")?;
let ordered_dict = collections.getattr("OrderedDict")?;
let result = ordered_dict.call0()?;
Ok(result.into())
}
#[cfg(feature = "python")]
pub fn create_naive_pandas_timestamp(py: Python, dt: DateTime<chrono::Utc>) -> PyResult<Py<PyAny>> {
let pandas = py.import("pandas")?;
let timestamp_cls = pandas.getattr("Timestamp")?;
let dt_naive = dt.naive_utc();
let iso_string = dt_naive.format("%Y-%m-%d %H:%M:%S").to_string();
let ts = timestamp_cls.call((iso_string,), None)?;
Ok(ts.into())
}
#[cfg(feature = "python")]
pub fn parse_python_datetime(dt: &Bound<PyAny>) -> PyResult<DateTime<Utc>> {
let py = dt.py();
let datetime_utc = if dt.hasattr("timestamp")? {
if dt.getattr("tzinfo")?.is_none() {
let calendar = py.import("calendar")?;
let timetuple = dt.call_method0("timetuple")?;
let secs: i64 = calendar.call_method1("timegm", (timetuple,))?.extract()?;
let microsecond: u32 = dt.getattr("microsecond")?.extract()?;
DateTime::from_timestamp(secs, microsecond * 1_000)
.ok_or_else(|| PyValueError::new_err("Invalid datetime"))?
} else {
return Err(PyValueError::new_err(
"dt 必须是 tz-naive datetime/Timestamp(项目约定:市场本地时间以 UTC 数值存储);\
tz-aware 入参会导致桶边界静默错位。请先在 Python 端 \
`df['dt'] = df['dt'].dt.tz_localize(None)`(或 `dt.replace(tzinfo=None)`)后再调用。",
));
}
} else if let Ok(timestamp) = dt.extract::<i64>() {
DateTime::from_timestamp(timestamp, 0)
.ok_or_else(|| PyValueError::new_err("Invalid timestamp for building object"))?
} else if let Ok(ts) = dt.extract::<f64>() {
DateTime::from_timestamp(ts as i64, (ts.fract() * 1_000_000_000.0) as u32)
.ok_or_else(|| PyValueError::new_err("Invalid timestamp"))?
} else {
return Err(PyValueError::new_err(
"dt must be datetime, Timestamp, or numeric timestamp",
));
};
Ok(datetime_utc)
}
pub fn freq_to_chinese_string(freq: Freq) -> &'static str {
match freq {
Freq::Tick => "Tick",
Freq::F1 => "1分钟",
Freq::F2 => "2分钟",
Freq::F3 => "3分钟",
Freq::F4 => "4分钟",
Freq::F5 => "5分钟",
Freq::F6 => "6分钟",
Freq::F10 => "10分钟",
Freq::F12 => "12分钟",
Freq::F15 => "15分钟",
Freq::F20 => "20分钟",
Freq::F30 => "30分钟",
Freq::F60 => "60分钟",
Freq::F120 => "120分钟",
Freq::F240 => "240分钟",
Freq::F360 => "360分钟",
Freq::D => "日线",
Freq::W => "周线",
Freq::M => "月线",
Freq::S => "季线",
Freq::Y => "年线",
}
}