
Timesfm Forecasting
Run TimesFM time-series forecasts and two-phase anomaly detection on real or synthetic series with plotted outputs.
Overview
TimesFM Forecasting is an agent skill most often used in Build (also Grow) that runs a two-phase Z-score plus TimesFM quantile anomaly workflow and exports PNG and JSON artifacts.
Install
npx skills add https://github.com/k-dense-ai/scientific-agent-skills --skill timesfm-forecastingWhat is this skill?
- Two-phase method: Phase 1 context detrend + Z-score on historical series; Phase 2 TimesFM quantile forecast bands
- Configurable severity bands: CRITICAL at Z≥3.0 and WARNING at Z≥2.0 with color-coded visualization
- Example pipeline uses NOAA temperature anomaly CSV with known Sep 2023 outlier and synthetic future anomalies
- Writes structured artifacts: output/anomaly_detection.png and output/anomaly_detection.json
- Quantile index mapping documented for mean, q10–q90 interval construction
- Default forecast horizon HORIZON=12
- Z thresholds: CRITICAL_Z=3.0 and WARNING_Z=2.0
- 36-month context window in documented NOAA example
Adoption & trust: 538 installs on skills.sh; 27.6k GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have seasonal metrics but no reproducible script that separates historical outliers from forecast-band breaches on future points.
Who is it for?
Builders prototyping ops or scientific monitoring with TimesFM who want copy-paste Python structure and explicit severity thresholds.
Skip if: Anyone needing a no-code BI-only forecast or a skill that installs and manages TimesFM cloud credentials without local scientific deps.
When should I use this skill?
When you need TimesFM-based forecast intervals plus context Z-score anomaly labels with exported visualization and JSON.
What do I get? / Deliverables
You get a committed example run with plotted context/forecast panels and JSON anomaly records you can adapt into monitoring jobs or agent reports.
- output/anomaly_detection.png two-panel chart
- output/anomaly_detection.json structured detection records
- Adaptable detect_context_anomalies and forecast-phase code paths
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Forecasting integrations land in Build when wiring scientific Python workflows into an agent-capable repo before growth analytics consume the results. Integrations subphase fits external model runtimes (TimesFM quantile intervals) plus artifact export (PNG, JSON).
Where it fits
Wire TimesFM horizon forecasts into a nightly job that writes JSON alerts for your agent.
Label WARNING vs CRITICAL KPI drift for a solo SaaS metrics review.
Compare live series against quantile bands after an infra or pricing change.
How it compares
Skill-packaged forecasting script with fixed two-phase logic—not a hosted MCP metrics server or generic spreadsheet trendline.
Common Questions / FAQ
Who is timesfm-forecasting for?
Indie builders and data-minded developers wiring time-series anomaly checks into agent repos or batch analytics pipelines.
When should I use timesfm-forecasting?
In Build when integrating TimesFM into a Python project, and in Grow when standing up analytics that need forecast intervals and outlier labels on KPI series.
Is timesfm-forecasting safe to install?
Check the Security Audits panel on this Prism page; the skill runs local Python, reads CSV paths, and writes output files—review deps and execution environment before running.
SKILL.md
READMESKILL.md - Timesfm Forecasting
#!/usr/bin/env python3 """ TimesFM Anomaly Detection Example — Two-Phase Method Phase 1 (context): Linear detrend + Z-score on 36 months of real NOAA temperature anomaly data (2022-01 through 2024-12). Sep 2023 (1.47 C) is a known critical outlier. Phase 2 (forecast): TimesFM quantile prediction intervals on a 12-month synthetic future with 3 injected anomalies. Outputs: output/anomaly_detection.png -- 2-panel visualization output/anomaly_detection.json -- structured detection records """ from __future__ import annotations import json from pathlib import Path import matplotlib matplotlib.use("Agg") import matplotlib.patches as mpatches import matplotlib.pyplot as plt import numpy as np import pandas as pd HORIZON = 12 DATA_FILE = ( Path(__file__).parent.parent / "global-temperature" / "temperature_anomaly.csv" ) OUTPUT_DIR = Path(__file__).parent / "output" CRITICAL_Z = 3.0 WARNING_Z = 2.0 # quant_fc index mapping: 0=mean, 1=q10, 2=q20, ..., 9=q90 IDX_Q10, IDX_Q20, IDX_Q80, IDX_Q90 = 1, 2, 8, 9 CLR = {"CRITICAL": "#e02020", "WARNING": "#f08030", "NORMAL": "#4a90d9"} # --------------------------------------------------------------------------- # Phase 1: context anomaly detection # --------------------------------------------------------------------------- def detect_context_anomalies( values: np.ndarray, dates: list, ) -> tuple[list[dict], np.ndarray, np.ndarray, float]: """Linear detrend + Z-score anomaly detection on context period. Returns ------- records : list of dicts, one per month trend_line : fitted linear trend values (same length as values) residuals : actual - trend_line res_std : std of residuals (used as sigma for threshold bands) """ n = len(values) idx = np.arange(n, dtype=float) coeffs = np.polyfit(idx, values, 1) trend_line = np.polyval(coeffs, idx) residuals = values - trend_line res_std = residuals.std() records = [] for i, (d, v, r) in enumerate(zip(dates, values, residuals)): z = r / res_std if res_std > 0 else 0.0 if abs(z) >= CRITICAL_Z: severity = "CRITICAL" elif abs(z) >= WARNING_Z: severity = "WARNING" else: severity = "NORMAL" records.append( { "date": str(d)[:7], "value": round(float(v), 4), "trend": round(float(trend_line[i]), 4), "residual": round(float(r), 4), "z_score": round(float(z), 3), "severity": severity, } ) return records, trend_line, residuals, res_std # --------------------------------------------------------------------------- # Phase 2: synthetic future + forecast anomaly detection # --------------------------------------------------------------------------- def build_synthetic_future( context: np.ndarray, n: int, seed: int = 42, ) -> tuple[np.ndarray, list[int]]: """Build a plausible future with 3 injected anomalies. Injected months: 3, 8, 11 (0-indexed within the 12-month horizon). Returns (future_values, injected_indices). """ rng = np.random.default_rng(seed) trend = np.linspace(context[-6:].mean(), context[-6:].mean() + 0.05, n) noise = rng.normal(0, 0.1, n) future = trend + noise injected = [3, 8, 11] future[3] += 0.7 # CRITICAL spike future[8] -= 0.65 # CRITICAL dip future[11] += 0.45 # WARNING spike return future.astype(np.float32), injected def detect_forecast_anomalies( future_values: np.ndarray, point: np.ndarray, quant_fc: np.ndarray, future_dates: list, injected_at: list[int], ) -> list[dict]: """Classify each forecast month by which PI band it falls outside. CRITICAL = outside 80% PI (q10-q90) WARNING = outside 60% PI (q20-q80) but inside 80% PI NORMAL = inside 60% PI """ q10 = quant_fc[IDX_Q10] q20 = quant_fc[IDX_Q20] q80 =