use crate::objects::freq::Freq;
use chrono::{DateTime, Utc};
#[cfg(feature = "python")]
use crate::objects::errors::ObjectError;
#[cfg(feature = "python")]
use anyhow::anyhow;
#[cfg(feature = "python")]
use pyo3::prelude::*;
#[cfg(feature = "python")]
use pyo3::types::PyAnyMethods;
#[cfg(feature = "python")]
pub fn create_ordered_dict(py: Python) -> PyResult<PyObject> {
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<PyObject> {
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 datetime_utc = if dt.hasattr("timestamp")? {
let timestamp = dt.call_method0("timestamp")?;
let timestamp_f64: f64 = timestamp.extract()?;
DateTime::from_timestamp(
timestamp_f64 as i64,
(timestamp_f64.fract() * 1_000_000_000.0) as u32,
)
.ok_or(ObjectError::Unexpected(anyhow!(
"Invalid datetime for building object"
)))?
} else if dt.hasattr("tz_localize")? {
let localized_dt = if dt.getattr("tz")?.is_none() {
dt.call_method1("tz_localize", ("UTC",))?
} else {
dt.clone()
};
let timestamp = localized_dt.call_method0("timestamp")?;
let timestamp_f64: f64 = timestamp.extract()?;
DateTime::from_timestamp(
timestamp_f64 as i64,
(timestamp_f64.fract() * 1_000_000_000.0) as u32,
)
.ok_or(ObjectError::Unexpected(anyhow!(
"Invalid datetime for building object"
)))?
} else if let Ok(timestamp) = dt.extract::<i64>() {
DateTime::from_timestamp(timestamp, 0).ok_or(ObjectError::Unexpected(anyhow!(
"Invalid timestamp for building object"
)))?
} else if let Ok(timestamp_f64) = dt.extract::<f64>() {
DateTime::from_timestamp(
timestamp_f64 as i64,
(timestamp_f64.fract() * 1_000_000_000.0) as u32,
)
.ok_or(ObjectError::Unexpected(anyhow!(
"Invalid timestamp for building object"
)))?
} else {
return Err(ObjectError::Unexpected(anyhow!(
"dt parameter must be a Python datetime object, pandas Timestamp, integer timestamp, or float timestamp"
))
.into());
};
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 => "年线",
}
}