use rustkernel_derive::KernelMessage;
use serde::{Deserialize, Serialize};
use crate::types::{
ARIMAParams, ARIMAResult, AnomalyMethod, ChangePointMethod, ChangePointResult,
DecompositionResult, GARCHParams, ProphetResult, TimeSeries, TimeSeriesAnomalyResult,
TrendMethod, TrendResult, VolatilityResult,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ARIMAForecastInput {
pub series: TimeSeries,
pub params: ARIMAParams,
pub horizon: usize,
}
impl ARIMAForecastInput {
pub fn new(series: TimeSeries, params: ARIMAParams, horizon: usize) -> Self {
Self {
series,
params,
horizon,
}
}
pub fn with_defaults(series: TimeSeries, horizon: usize) -> Self {
Self {
series,
params: ARIMAParams::new(1, 1, 1),
horizon,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ARIMAForecastOutput {
pub result: ARIMAResult,
pub compute_time_us: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProphetDecompositionInput {
pub series: TimeSeries,
pub period: Option<usize>,
pub horizon: usize,
}
impl ProphetDecompositionInput {
pub fn new(series: TimeSeries, period: Option<usize>, horizon: usize) -> Self {
Self {
series,
period,
horizon,
}
}
pub fn with_period(series: TimeSeries, period: usize, horizon: usize) -> Self {
Self {
series,
period: Some(period),
horizon,
}
}
pub fn without_seasonality(series: TimeSeries, horizon: usize) -> Self {
Self {
series,
period: None,
horizon,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProphetDecompositionOutput {
pub result: ProphetResult,
pub compute_time_us: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChangePointDetectionInput {
pub series: TimeSeries,
pub method: ChangePointMethod,
pub penalty: f64,
pub min_segment: usize,
}
impl ChangePointDetectionInput {
pub fn new(
series: TimeSeries,
method: ChangePointMethod,
penalty: f64,
min_segment: usize,
) -> Self {
Self {
series,
method,
penalty,
min_segment,
}
}
pub fn pelt(series: TimeSeries, penalty: f64) -> Self {
Self {
series,
method: ChangePointMethod::PELT,
penalty,
min_segment: 10,
}
}
pub fn binary_segmentation(series: TimeSeries, penalty: f64) -> Self {
Self {
series,
method: ChangePointMethod::BinarySegmentation,
penalty,
min_segment: 10,
}
}
pub fn cusum(series: TimeSeries, threshold: f64) -> Self {
Self {
series,
method: ChangePointMethod::CUSUM,
penalty: threshold,
min_segment: 10,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChangePointDetectionOutput {
pub result: ChangePointResult,
pub compute_time_us: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, KernelMessage)]
#[message(type_id = 2020, domain = "TemporalAnalysis")]
pub struct TimeSeriesAnomalyDetectionInput {
pub series: TimeSeries,
pub method: AnomalyMethod,
pub threshold: f64,
pub window: Option<usize>,
}
impl TimeSeriesAnomalyDetectionInput {
pub fn new(
series: TimeSeries,
method: AnomalyMethod,
threshold: f64,
window: Option<usize>,
) -> Self {
Self {
series,
method,
threshold,
window,
}
}
pub fn zscore(series: TimeSeries, threshold: f64) -> Self {
Self {
series,
method: AnomalyMethod::ZScore,
threshold,
window: None,
}
}
pub fn rolling_zscore(series: TimeSeries, threshold: f64, window: usize) -> Self {
Self {
series,
method: AnomalyMethod::ZScore,
threshold,
window: Some(window),
}
}
pub fn iqr(series: TimeSeries, multiplier: f64) -> Self {
Self {
series,
method: AnomalyMethod::IQR,
threshold: multiplier,
window: None,
}
}
pub fn moving_average(series: TimeSeries, threshold: f64, window: usize) -> Self {
Self {
series,
method: AnomalyMethod::MovingAverageDeviation,
threshold,
window: Some(window),
}
}
pub fn seasonal_esd(series: TimeSeries, threshold: f64, period: usize) -> Self {
Self {
series,
method: AnomalyMethod::SeasonalESD,
threshold,
window: Some(period),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, KernelMessage)]
#[message(type_id = 2021, domain = "TemporalAnalysis")]
pub struct TimeSeriesAnomalyDetectionOutput {
pub result: TimeSeriesAnomalyResult,
pub compute_time_us: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SeasonalDecompositionInput {
pub series: TimeSeries,
pub period: usize,
pub robust: bool,
}
impl SeasonalDecompositionInput {
pub fn new(series: TimeSeries, period: usize, robust: bool) -> Self {
Self {
series,
period,
robust,
}
}
pub fn standard(series: TimeSeries, period: usize) -> Self {
Self {
series,
period,
robust: false,
}
}
pub fn robust(series: TimeSeries, period: usize) -> Self {
Self {
series,
period,
robust: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SeasonalDecompositionOutput {
pub result: DecompositionResult,
pub compute_time_us: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TrendExtractionInput {
pub series: TimeSeries,
pub method: TrendMethod,
pub window: usize,
}
impl TrendExtractionInput {
pub fn new(series: TimeSeries, method: TrendMethod, window: usize) -> Self {
Self {
series,
method,
window,
}
}
pub fn simple_ma(series: TimeSeries, window: usize) -> Self {
Self {
series,
method: TrendMethod::SimpleMovingAverage,
window,
}
}
pub fn ema(series: TimeSeries, span: usize) -> Self {
Self {
series,
method: TrendMethod::ExponentialMovingAverage,
window: span,
}
}
pub fn centered_ma(series: TimeSeries, window: usize) -> Self {
Self {
series,
method: TrendMethod::CenteredMovingAverage,
window,
}
}
pub fn lowess(series: TimeSeries, bandwidth: usize) -> Self {
Self {
series,
method: TrendMethod::Lowess,
window: bandwidth,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TrendExtractionOutput {
pub result: TrendResult,
pub compute_time_us: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, KernelMessage)]
#[message(type_id = 2050, domain = "TemporalAnalysis")]
pub struct VolatilityAnalysisInput {
pub returns: TimeSeries,
pub params: GARCHParams,
pub forecast_horizon: usize,
}
impl VolatilityAnalysisInput {
pub fn new(returns: TimeSeries, params: GARCHParams, forecast_horizon: usize) -> Self {
Self {
returns,
params,
forecast_horizon,
}
}
pub fn garch_1_1(returns: TimeSeries, forecast_horizon: usize) -> Self {
Self {
returns,
params: GARCHParams::new(1, 1),
forecast_horizon,
}
}
pub fn garch(returns: TimeSeries, p: usize, q: usize, forecast_horizon: usize) -> Self {
Self {
returns,
params: GARCHParams::new(p, q),
forecast_horizon,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, KernelMessage)]
#[message(type_id = 2051, domain = "TemporalAnalysis")]
pub struct VolatilityAnalysisOutput {
pub result: VolatilityResult,
pub compute_time_us: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, KernelMessage)]
#[message(type_id = 2052, domain = "TemporalAnalysis")]
pub struct EWMAVolatilityInput {
pub returns: TimeSeries,
pub lambda: f64,
pub forecast_horizon: usize,
}
impl EWMAVolatilityInput {
pub fn new(returns: TimeSeries, lambda: f64, forecast_horizon: usize) -> Self {
Self {
returns,
lambda,
forecast_horizon,
}
}
pub fn riskmetrics(returns: TimeSeries, forecast_horizon: usize) -> Self {
Self {
returns,
lambda: 0.94,
forecast_horizon,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, KernelMessage)]
#[message(type_id = 2053, domain = "TemporalAnalysis")]
pub struct EWMAVolatilityOutput {
pub result: VolatilityResult,
pub compute_time_us: u64,
}