Forecasting Module for DGS10 & VIXCLS (ARIMA/GARCH) with API + UI
#4 opened on Dec 7, 2025
Repository metrics
- Stars
- (18 stars)
- PR merge metrics
- (PR metrics pending)
Description
Summary
Add a proper time-series forecasting path for DGS10 (10-Year Treasury) and VIXCLS that outperforms simple regressions. Implement ARIMA (baseline) and GARCH (volatility) models offline, persist forecasts to MongoDB, expose them via the Express API, and visualize in the React frontend with confidence bands + backtest metrics.
Why
Per the repo’s report, linear/polynomial/log models have very low (R^2) for DGS10/VIXCLS. These series are better modeled with time-series methods that capture autocorrelation and conditional volatility. This issue adds that capability end-to-end.
Scope
-
Models:
- ARIMA(p,d,q) for mean process (both series).
- GARCH(1,1) (on residuals) for VIXCLS (optional but preferred).
-
Data cadence: reuse existing cleaned series from MongoDB.
-
Persist per model: horizon (e.g., 30/90 days), forecast mean, 95% CI, fit diagnostics.
-
API:
GET /api/forecast/:series?horizon=30returning latest stored forecast payload. -
UI: new “Forecast” tab on Charts page with toggles for horizon and model; show line chart with CI band and a small backtest panel (MAE/MAPE).
Acceptance Criteria
-
A script produces forecasts for DGS10 and VIXCLS with ARIMA; VIXCLS supports GARCH when enabled.
-
Forecasts (point + upper/lower 95% CI) are written to MongoDB with timestamps and model params.
-
GET /api/forecast/DGS10?horizon=30and…/VIXCLSreturn JSON:{ "series":"DGS10", "horizon":30, "generatedAt":"2025-12-07T00:00:00Z", "model":{"type":"ARIMA","params":{"p":1,"d":1,"q":1}}, "metrics":{"mae":..., "mape":..., "rmse":...}, "points":[{"date":"2026-01-01","mean":..., "lo":..., "hi":...}, ...] } -
Frontend renders forecast line + shaded CI and can switch horizon (30/90) and model (ARIMA/GARCH if available).
-
Backtest (rolling origin over last N points) displayed with MAE/MAPE and last retrain time.
-
CI bandwidth and tooltips respect dark/light theme; no layout shift.
Implementation Notes
-
Where to run models: keep modeling offline to avoid runtime heavy deps on Vercel. Add a
backend/src/jobs/forecast.tsscript that:- fetches latest series from MongoDB, 2) fits ARIMA (and GARCH for VIXCLS), 3) writes forecast docs.
-
Modeling runtime options (pick one):
- Python sidecar (recommended): call a tiny Python script via
child_processusingstatsmodels+arch. JSON in/out. - Node-only fallback: use
arimanpm for ARIMA; skip GARCH if library scarcity is an issue.
- Python sidecar (recommended): call a tiny Python script via
-
Storage design:
forecastscollection keyed by{ series, horizon, model.type }withgeneratedAtindex; keep last K snapshots. -
API: add
routes/forecast.tsto read the latest snapshot per query. -
UI:
- Add
/frontend/src/components/ForecastChart.tsxusing RechartsArea(for CI) +Line(mean). - Dropdowns for Model + Horizon; small
Cardfor MAE/MAPE and “Last updated”.
- Add
Tasks
- Backend: create
forecast.tsjob (Node orchestrator). - (Option A) Add
python/forecast.pywith ARIMA/GARCH; wire viachild_process. - Mongo schema + indexes (
series,horizon,model.type,generatedAt). - API:
GET /api/forecast/:series. - Frontend:
ForecastChart.tsx+ tab on Charts page; controls for model/horizon. - Backtest util: rolling origin over last 180 days; compute MAE/MAPE/RMSE; store in snapshot.
- Docs: README “Forecasts” section with how to run the job and interpret CI.
- CI: optional GitHub Action to run the job nightly and push results.
Out of Scope (follow-ups)
- Prophet/ETS comparisons; multivariate (VAR) with macro covariates; live on-demand training in API.