anofox-forecast
Technical depth grading and code quality analysis powered by pmat
Time series forecasting library for Rust.
Provides 40+ forecasting models, 76+ statistical features, automatic model selection, ensemble methods, seasonality decomposition, changepoint detection, anomaly detection, hierarchical reconciliation, and model serialization.
Use Cases
Need to run this on 10GB of data? Use our DuckDB extension for SQL-native forecasting at scale.
Need to use this in a React Dashboard? Use our npm package for WebAssembly-powered forecasting in the browser.
import init from '@sipemu/anofox-forecast';
await ;
const ts = ;
const model = ;
model.;
const forecast = model.;
console.log;
Features
-
Forecasting Models (40+)
- ARIMA, SARIMA, and AutoARIMA with automatic order selection
- Exponential Smoothing: SES, Holt's Linear, Holt-Winters, SeasonalES
- ETS (Error-Trend-Seasonal) state-space framework with AutoETS
- Baseline methods: Naive, Seasonal Naive, Random Walk with Drift, SMA, Window Average
- Theta family: Theta, Optimized Theta, Dynamic Theta, AutoTheta
- Intermittent demand: Croston, ADIDA, TSB, IMAPA
- TBATS/AutoTBATS for complex seasonality
- MFLES (Multiple Frequency Locally Estimated Scatterplot)
- MSTL-based forecasting with configurable trend/seasonal methods
- GARCH for volatility modeling
- VAR (Vector Autoregression) for multivariate forecasting with Granger causality
- Kalman filter / state-space models (local level, local linear trend, custom)
- Exogenous regressor support across model families
-
Automatic Model Selection
AutoForecast: Unified selection across ARIMA, ETS, and Theta families (parallel withparallelfeature)AutoEnsemble: Automatic ensemble of top-K best models- Selection by in-sample MSE or cross-validation error
- Builder API:
AutoForecast::builder().seasonal_period(12).include_arima(true).build() fit_predict()convenience method on all models
-
Batch Processing & Parallelism
fit_predict_many(): Fit one model across many series (parallel withparallelfeature)fit_registry(): Fit all registered models on a series (parallel)compare_models()/compare_registry(): Parallel model comparison- Cross-validation folds run in parallel when
parallelfeature is enabled - Bootstrap sampling uses
par_iterwhenparallelis enabled
-
Ensemble Methods
- Mean, Median, Weighted MSE, and Custom weight combination strategies
- Widest-envelope interval combination for ensemble prediction intervals
- Automatic ensemble construction from model registry
-
Model Comparison & Evaluation
compare_models(): Side-by-side model evaluation with timingcompare_registry(): Compare all registered models at once- Accuracy metrics: MAE, MSE, RMSE, MAPE, sMAPE, MASE, and more
- Time series cross-validation with configurable strategies
rolling_forecast(): Walk-forward evaluation with rolling/expanding windows- Streaming CV aggregation with early stopping (
cross_validate_early_stop()) - Residual diagnostics: Ljung-Box, Durbin-Watson, Jarque-Bera, Box-Pierce
diagnose_residuals(): Unified residual diagnostic report
-
Time Series Feature Extraction (76+ features)
- Basic statistics (mean, variance, quantiles, energy, etc.)
- Distribution features (skewness, kurtosis, symmetry)
- Autocorrelation and partial autocorrelation
- Entropy features (approximate, sample, permutation, binned, Fourier)
- Complexity measures (C3, CID, Lempel-Ziv)
- Trend analysis and stationarity tests (ADF, KPSS)
- Automated feature selection (variance threshold, correlation filter, top-K)
-
Spectral Analysis
- Welch's periodogram for reduced variance spectral estimation
- For comprehensive periodicity detection, see fdars
-
Seasonality & Decomposition
- STL (Seasonal-Trend decomposition using LOESS) with
StlBuilderfor ergonomic configuration - MSTL (Multiple Seasonal-Trend decomposition) for complex seasonality
- Prophet-style Fourier seasonality (
FourierSeasonality) with flexible harmonic modeling TimeSeries::seasonal_strength()/trend_strength()— quick strength assessment
- STL (Seasonal-Trend decomposition using LOESS) with
-
Hierarchical Forecasting
HierarchyTree: Define parent-children structure for grouped series- Bottom-up, top-down, and MinTrace OLS reconciliation methods
- Ensures coherent forecasts across hierarchical levels
-
Changepoint Detection
- PELT algorithm with O(n) average complexity
- Builder API:
Pelt::new(CostFunction::L2).min_size(5).penalty(5.0).detect(&data) - Multiple cost functions: L1, L2, Normal, Poisson, LinearTrend, MeanVariance, Cusum
-
Anomaly Detection & Outlier Handling
- Statistical methods (IQR, z-score, modified z-score)
- Automatic threshold selection
TimeSeries::with_outliers_replaced()— automatic outlier replacement with local median
-
Bootstrap Confidence Intervals
- Residual bootstrap and block bootstrap methods
- Empirical confidence intervals for any model
- Configurable sample size and reproducibility
-
Probabilistic Postprocessing
- Conformal Prediction: Distribution-free intervals with coverage guarantees
- Historical Simulation: Non-parametric empirical error distribution
- Normal Predictor: Gaussian error assumption baseline
- IDR: Isotonic Distributional Regression (state-of-the-art calibration)
- QRA: Quantile Regression Averaging for ensemble combining
- Backtesting: Rolling/expanding window evaluation with horizon-aware calibration
-
Model Serialization (optional
serdefeature)- Save/load models to JSON with
to_json()/from_json() - Binary serialization with
to_bincode()/from_bincode()for compact storage - File persistence with
save_to_file()/load_from_file() - Round-trip serialization for all major model families
- Save/load models to JSON with
-
Missing Value Imputation
- Policy-based: Drop, Fill, ForwardFill, BackwardFill, FillMean, FillMedian, Interpolate
- Advanced: moving average imputation, seasonal median imputation
- Convenience: forward-backward fill, regressor imputation
- Metadata: missing mask, per-dimension missing counts
-
Data Transformations
- Scaling: standardization, min-max, robust scaling
- Box-Cox transformation with automatic lambda selection
- Window functions: rolling mean, std, min, max, median
- Exponential weighted moving averages
Installation
Add this to your Cargo.toml:
[]
= "0.4"
Optional Features
[]
# Parallel AutoARIMA (4-8x speedup via rayon, opt-in for embedding contexts like DuckDB)
= { = "0.4", = ["parallel"] }
# Model serialization (save/load to JSON)
= { = "0.4", = ["serde"] }
# Probabilistic postprocessing (conformal, IDR, QRA — enabled by default)
= { = "0.4", = false } # to disable
| Feature | Default | Description |
|---|---|---|
postprocess |
Yes | Conformal prediction, IDR, QRA, historical simulation |
parallel |
No | Rayon-based parallelism for AutoARIMA, AutoForecast, batch processing, bootstrap, and cross-validation (not available on WASM) |
serde |
No | JSON and bincode serialization/deserialization for models |
Quick Start
Creating a Time Series
use *;
use ;
// Create timestamps
let timestamps: =
.map
.collect;
// Create values
let values: = .map.collect;
// Build the time series
let ts = builder
.timestamps
.values
.build?;
Automatic Model Selection
use *;
use AutoForecast;
// Automatically selects the best model across ARIMA, ETS, and Theta
let mut model = new;
model.fit?;
let forecast = model.predict?;
println!;
ARIMA Forecasting
use *;
use ARIMA;
// Create and fit an ARIMA(1,1,1) model
let mut model = ARIMAnew;
model.fit?;
// Generate forecasts with 95% confidence intervals
let forecast = model.predict_with_intervals?;
println!;
println!;
println!;
Holt-Winters Forecasting
use HoltWinters;
// Create Holt-Winters with additive seasonality (period = 12)
let mut model = additive;
model.fit?;
let forecast = model.predict?;
Model Comparison
use ;
use ;
// Compare all registered models side-by-side
let config = default;
let table = compare_registry?;
println!;
Feature Extraction
use ;
let values = ts.values;
let m = mean;
let v = variance;
let s = skewness;
let ae = approximate_entropy?;
println!;
STL Decomposition
use Stl;
// Decompose with seasonal period of 12
let stl = new?;
let decomposition = stl.decompose?;
println!;
println!;
println!;
Changepoint Detection
use ;
let pelt = new?;
let changepoints = pelt.detect?;
println!;
Spectral Analysis
use welch_periodogram;
// Welch's periodogram with overlapping windows
let psd = welch_periodogram;
// Find dominant period
if let Some = psd.iter.max_by
For comprehensive periodicity detection (ACF, FFT, Autoperiod, CFD-Autoperiod, SAZED), see the fdars crate.
Probabilistic Postprocessing
use ;
// Historical forecasts and actuals for calibration
let train_forecasts = from_values;
let train_actuals = vec!;
// Create a conformal predictor with 90% coverage
let processor = conformal;
// Backtest with horizon-aware calibration
let config = new
.initial_window
.step
.horizon
.horizon_aware;
let results = processor.backtest?;
println!;
// Train calibrated model and predict
let trained = processor.train?;
let new_forecasts = from_values;
let intervals = processor.predict_intervals?;
println!;
println!;
API Reference
Core Types
| Type | Description |
|---|---|
TimeSeries |
Main data structure for univariate/multivariate time series |
Forecast |
Prediction results with optional confidence intervals |
Forecaster |
Trait implemented by all forecasting models |
AccuracyMetrics |
Model evaluation metrics (MAE, MSE, RMSE, MAPE, etc.) |
Forecasting Models
| Family | Models |
|---|---|
| Auto Selection | AutoForecast, AutoEnsemble |
| ARIMA | ARIMA, SARIMA, AutoARIMA |
| Exponential Smoothing | SES, Holt, HoltWinters, SeasonalES, ETS, AutoETS |
| Theta | Theta, OptimizedTheta, DynamicTheta, AutoTheta |
| Baseline | Naive, Mean, SeasonalNaive, RandomWalkWithDrift, SMA, WindowAverage, SeasonalWindowAverage |
| Intermittent | Croston, TSB, ADIDA, IMAPA |
| Complex Seasonality | TBATS, AutoTBATS, MFLES, MSTLForecaster |
| Volatility | GARCH |
| Multivariate | VAR (Vector Autoregression) |
| State-Space | KalmanFilter, StateSpaceModel (local level, local linear trend) |
| Ensemble | Ensemble (Mean, Median, Weighted MSE, Custom) |
| Hierarchical | HierarchyTree (BottomUp, TopDown, MinTraceOls reconciliation) |
Utilities
| Function / Type | Description |
|---|---|
compare_models() |
Compare forecasters on the same data with timing |
compare_registry() |
Compare all registered models at once |
cross_validate() |
Time series cross-validation (parallel with parallel feature) |
cross_validate_early_stop() |
CV with convergence-based early stopping |
rolling_forecast() |
Walk-forward evaluation with rolling/expanding windows |
StreamingCVAggregator |
Online metric aggregation using Welford's algorithm |
fit_predict_many() |
Batch fit-predict across multiple series |
bootstrap_forecast() |
Bootstrap confidence intervals for any model |
diagnose_residuals() |
Unified residual diagnostics (Ljung-Box, DW, Jarque-Bera) |
select_features() |
Automated feature selection (variance, correlation, top-K) |
to_json() / from_json() |
Serialization for models, Forecast, and TimeSeries (requires serde feature) |
to_bincode() / from_bincode() |
Binary serialization (requires serde feature) |
Feature Categories
| Category | Examples |
|---|---|
| Basic | mean, variance, minimum, maximum, quantile |
| Distribution | skewness, kurtosis, variation_coefficient |
| Autocorrelation | autocorrelation, partial_autocorrelation |
| Entropy | approximate_entropy, sample_entropy, permutation_entropy |
| Complexity | c3, cid_ce, lempel_ziv_complexity |
| Trend | linear_trend, adf_test, ar_coefficient |
| Selection | select_features, rank_features |
Postprocessing Types
| Type | Description |
|---|---|
PostProcessor |
Unified API for all postprocessing methods |
ConformalPredictor |
Distribution-free prediction intervals |
HistoricalSimulator |
Empirical error distribution |
IDRPredictor |
Isotonic Distributional Regression |
QRAPredictor |
Quantile Regression Averaging |
Guides
- Model Selection Guide — Which model to use for your data
Dependencies
- chrono - Date and time handling
- trueno - Linear algebra operations
- statrs - Statistical distributions and functions
- thiserror - Error handling
- rand - Random number generation
- rustfft - Fast Fourier Transform for spectral analysis
Acknowledgments
The postprocessing module is a Rust port of PostForecasts.jl. Feature extraction is inspired by tsfresh. Forecasting models are validated against StatsForecast by Nixtla. See THIRDPARTY_NOTICE.md for full attribution and references to the research papers that inspired this implementation.
License
MIT License - see LICENSE for details.