Install
$ agentstack add skill-zlanqing-codex-claude-academic-skills-timesfm-forecasting ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
TimesFM Forecasting
Overview
TimesFM (Time Series Foundation Model) is a pretrained decoder-only foundation model developed by Google Research for time-series forecasting. It works zero-shot — feed it any univariate time series and it returns point forecasts with calibrated quantile prediction intervals, no training required.
This skill wraps TimesFM for safe, agent-friendly local inference. It includes a mandatory preflight system checker that verifies RAM, GPU memory, and disk space before the model is ever loaded so the agent never crashes a user's machine.
> Key numbers: TimesFM 2.5 uses 200M parameters (~800 MB on disk, ~1.5 GB in RAM on > CPU, ~1 GB VRAM on GPU). The archived v1/v2 500M-parameter model needs ~32 GB RAM. > Always run the system checker first.
When to Use This Skill
Use this skill when:
- Forecasting any univariate time series (sales, demand, sensor, vitals, price, weather)
- You need zero-shot forecasting without training a custom model
- You want probabilistic forecasts with calibrated prediction intervals (quantiles)
- You have time series of any length (the model handles 1–16,384 context points)
- You need to batch-forecast hundreds or thousands of series efficiently
- You want a foundation model approach instead of hand-tuning ARIMA/ETS parameters
Do not use this skill when:
- You need classical statistical models with coefficient interpretation → use
statsmodels - You need time series classification or clustering → use
aeon - You need multivariate vector autoregression or Granger causality → use
statsmodels - Your data is tabular (not temporal) → use
scikit-learn
> Note on Anomaly Detection: TimesFM does not have built-in anomaly detection, but you can > use the quantile forecasts as prediction intervals — values outside the 90% CI (q10–q90) > are statistically unusual. See the examples/anomaly-detection/ directory for a full example.
⚠️ Mandatory Preflight: System Requirements Check
CRITICAL — ALWAYS run the system checker before loading the model for the first time.
python scripts/check_system.py
This script checks:
- Available RAM — warns if below 4 GB, blocks if below 2 GB
- GPU availability — detects CUDA/MPS devices and VRAM
- Disk space — verifies room for the ~800 MB model download
- Python version — requires 3.10+
- Existing installation — checks if
timesfmandtorchare installed
> Note: Model weights are NOT stored in this repository. TimesFM weights (~800 MB) > download on-demand from HuggingFace on first use and cache in ~/.cache/huggingface/. > The preflight checker ensures sufficient resources before any download begins.
flowchart TD
accTitle: Preflight System Check
accDescr: Decision flowchart showing the system requirement checks that must pass before loading TimesFM.
start["🚀 Run check_system.py"] --> ram{"RAM ≥ 4 GB?"}
ram -->|"Yes"| gpu{"GPU available?"}
ram -->|"No (2-4 GB)"| warn_ram["⚠️ Warning: tight RAMCPU-only, small batches"]
ram -->|"No (Insufficient memory"]
warn_ram --> disk
gpu -->|"CUDA / MPS"| vram{"VRAM ≥ 2 GB?"}
gpu -->|"CPU only"| cpu_ok["✅ CPU modeSlower but works"]
vram -->|"Yes"| gpu_ok["✅ GPU modeFast inference"]
vram -->|"No"| cpu_ok
gpu_ok --> disk{"Disk ≥ 2 GB free?"}
cpu_ok --> disk
disk -->|"Yes"| ready["✅ READYSafe to load model"]
disk -->|"No"| block_disk["🛑 BLOCKEDNeed space for weights"]
classDef ok fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d
classDef warn fill:#fef9c3,stroke:#ca8a04,stroke-width:2px,color:#713f12
classDef block fill:#fee2e2,stroke:#dc2626,stroke-width:2px,color:#7f1d1d
classDef neutral fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#1f2937
class ready,gpu_ok,cpu_ok ok
class warn_ram warn
class block,block_disk block
class start,ram,gpu,vram,disk neutral
Hardware Requirements by Model Version
| Model | Parameters | RAM (CPU) | VRAM (GPU) | Disk | Context | | ----- | ---------- | --------- | ---------- | ---- | ------- | | TimesFM 2.5 (recommended) | 200M | ≥ 4 GB | ≥ 2 GB | ~800 MB | up to 16,384 | | TimesFM 2.0 (archived) | 500M | ≥ 16 GB | ≥ 8 GB | ~2 GB | up to 2,048 | | TimesFM 1.0 (archived) | 200M | ≥ 8 GB | ≥ 4 GB | ~800 MB | up to 2,048 |
> Recommendation: Always use TimesFM 2.5 unless you have a specific reason to use an > older checkpoint. It is smaller, faster, and supports 8× longer context.
🔧 Installation
Step 1: Verify System (always first)
python scripts/check_system.py
Step 2: Install TimesFM
# Using uv (recommended by this repo)
uv pip install timesfm[torch]
# Or using pip
pip install timesfm[torch]
# For JAX/Flax backend (faster on TPU/GPU)
uv pip install timesfm[flax]
Step 3: Install PyTorch for Your Hardware
# CUDA 12.1 (NVIDIA GPU)
pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cu121
# CPU only
pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cpu
# Apple Silicon (MPS)
pip install torch>=2.0.0 # MPS support is built-in
Step 4: Verify Installation
import timesfm
import numpy as np
print(f"TimesFM version: {timesfm.__version__}")
print("Installation OK")
🎯 Quick Start
Minimal Example (5 Lines)
import torch, numpy as np, timesfm
torch.set_float32_matmul_precision("high")
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch"
)
model.compile(timesfm.ForecastConfig(
max_context=1024, max_horizon=256, normalize_inputs=True,
use_continuous_quantile_head=True, force_flip_invariance=True,
infer_is_positive=True, fix_quantile_crossing=True,
))
point, quantiles = model.forecast(horizon=24, inputs=[
np.sin(np.linspace(0, 20, 200)), # any 1-D array
])
# point.shape == (1, 24) — median forecast
# quantiles.shape == (1, 24, 10) — 10th–90th percentile bands
Forecast from CSV
import pandas as pd, numpy as np
df = pd.read_csv("monthly_sales.csv", parse_dates=["date"], index_col="date")
# Convert each column to a list of arrays
inputs = [df[col].dropna().values.astype(np.float32) for col in df.columns]
point, quantiles = model.forecast(horizon=12, inputs=inputs)
# Build a results DataFrame
for i, col in enumerate(df.columns):
last_date = df[col].dropna().index[-1]
future_dates = pd.date_range(last_date, periods=13, freq="MS")[1:]
forecast_df = pd.DataFrame({
"date": future_dates,
"forecast": point[i],
"lower_80": quantiles[i, :, 2], # 20th percentile
"upper_80": quantiles[i, :, 8], # 80th percentile
})
print(f"\n--- {col} ---")
print(forecast_df.to_string(index=False))
Forecast with Covariates (XReg)
TimesFM 2.5+ supports exogenous variables through forecast_with_covariates(). Requires timesfm[xreg].
# Requires: uv pip install timesfm[xreg]
point, quantiles = model.forecast_with_covariates(
inputs=inputs,
dynamic_numerical_covariates={"price": price_arrays},
dynamic_categorical_covariates={"holiday": holiday_arrays},
static_categorical_covariates={"region": region_labels},
xreg_mode="xreg + timesfm", # or "timesfm + xreg"
)
| Covariate Type | Description | Example | | -------------- | ----------- | ------- | | dynamic_numerical | Time-varying numeric | price, temperature, promotion spend | | dynamic_categorical | Time-varying categorical | holiday flag, day of week | | static_numerical | Per-series numeric | store size, account age | | static_categorical | Per-series categorical | store type, region, product category |
XReg Modes:
"xreg + timesfm"(default): TimesFM forecasts first, then XReg adjusts residuals"timesfm + xreg": XReg fits first, then TimesFM forecasts residuals
> See examples/covariates-forecasting/ for a complete example with synthetic retail data.
Anomaly Detection (via Quantile Intervals)
TimesFM does not have built-in anomaly detection, but the quantile forecasts naturally provide prediction intervals that can detect anomalies:
point, q = model.forecast(horizon=H, inputs=[values])
# 90% prediction interval
lower_90 = q[0, :, 1] # 10th percentile
upper_90 = q[0, :, 9] # 90th percentile
# Detect anomalies: values outside the 90% CI
actual = test_values # your holdout data
anomalies = (actual upper_90)
# Severity levels
is_warning = (actual q[0, :, 8]) # outside 80% CI
is_critical = anomalies # outside 90% CI
| Severity | Condition | Interpretation | | -------- | --------- | -------------- | | Normal | Inside 80% CI | Expected behavior | | Warning | Outside 80% CI | Unusual but possible | | Critical | Outside 90% CI | Statistically rare ( See examples/anomaly-detection/ for a complete example with visualization.
# Requires: uv pip install timesfm[xreg]
point, quantiles = model.forecast_with_covariates(
inputs=inputs,
dynamic_numerical_covariates={"temperature": temp_arrays},
dynamic_categorical_covariates={"day_of_week": dow_arrays},
static_categorical_covariates={"region": region_labels},
xreg_mode="xreg + timesfm", # or "timesfm + xreg"
)
📊 Understanding the Output
Quantile Forecast Structure
TimesFM returns (point_forecast, quantile_forecast):
point_forecast: shape(batch, horizon)— the median (0.5 quantile)quantile_forecast: shape(batch, horizon, 10)— ten slices:
| Index | Quantile | Use | | ----- | -------- | --- | | 0 | Mean | Average prediction | | 1 | 0.1 | Lower bound of 80% PI | | 2 | 0.2 | Lower bound of 60% PI | | 3 | 0.3 | — | | 4 | 0.4 | — | | 5 | 0.5 | Median (= point_forecast) | | 6 | 0.6 | — | | 7 | 0.7 | — | | 8 | 0.8 | Upper bound of 60% PI | | 9 | 0.9 | Upper bound of 80% PI |
Extracting Prediction Intervals
point, q = model.forecast(horizon=H, inputs=data)
# 80% prediction interval (most common)
lower_80 = q[:, :, 1] # 10th percentile
upper_80 = q[:, :, 9] # 90th percentile
# 60% prediction interval (tighter)
lower_60 = q[:, :, 2] # 20th percentile
upper_60 = q[:, :, 8] # 80th percentile
# Median (same as point forecast)
median = q[:, :, 5]
flowchart LR
accTitle: Quantile Forecast Anatomy
accDescr: Diagram showing how the 10-element quantile vector maps to prediction intervals.
input["📈 Input Series1-D array"] --> model["🤖 TimesFMcompile + forecast"]
model --> point["📍 Point Forecast(batch, horizon)"]
model --> quant["📊 Quantile Forecast(batch, horizon, 10)"]
quant --> pi80["80% PIq[:,:,1] – q[:,:,9]"]
quant --> pi60["60% PIq[:,:,2] – q[:,:,8]"]
quant --> median["Medianq[:,:,5]"]
classDef data fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e3a5f
classDef model fill:#f3e8ff,stroke:#9333ea,stroke-width:2px,color:#581c87
classDef output fill:#dcfce7,stroke:#16a34a,stroke-width:2px,color:#14532d
class input data
class model model
class point,quant,pi80,pi60,median output
🔧 ForecastConfig Reference
All forecasting behavior is controlled by timesfm.ForecastConfig:
timesfm.ForecastConfig(
max_context=1024, # Max context window (truncates longer series)
max_horizon=256, # Max forecast horizon
normalize_inputs=True, # Normalize inputs (RECOMMENDED for stability)
per_core_batch_size=32, # Batch size per device (tune for memory)
use_continuous_quantile_head=True, # Better quantile accuracy for long horizons
force_flip_invariance=True, # Ensures f(-x) = -f(x) (mathematical consistency)
infer_is_positive=True, # Clamp forecasts ≥ 0 when all inputs > 0
fix_quantile_crossing=True, # Ensure q10 ≤ q20 ≤ ... ≤ q90
return_backcast=False, # Return backcast (for covariate workflows)
)
| Parameter | Default | When to Change | | --------- | ------- | -------------- | | max_context | 0 | Set to match your longest historical window (e.g., 512, 1024, 4096) | | max_horizon | 0 | Set to your maximum forecast length | | normalize_inputs | False | Always set True — prevents scale-dependent instability | | per_core_batch_size | 1 | Increase for throughput; decrease if OOM | | use_continuous_quantile_head | False | Set True for calibrated prediction intervals | | force_flip_invariance | True | Keep True unless profiling shows it hurts | | infer_is_positive | True | Set False for series that can be negative (temperature, returns) | | fix_quantile_crossing | False | Set True to guarantee monotonic quantiles |
📋 Common Workflows
Workflow 1: Single Series Forecast
flowchart TD
accTitle: Single Series Forecast Workflow
accDescr: Step-by-step workflow for forecasting a single time series with system checking.
check["1. Run check_system.py"] --> load["2. Load modelfrom_pretrained()"]
load --> compile["3. Compile with ForecastConfig"]
compile --> prep["4. Prepare datapd.read_csv → np.array"]
prep --> forecast["5. model.forecast()horizon=N"]
forecast --> extract["6. Extract point + PI"]
extract --> plot["7. Plot or export results"]
classDef step fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#1f2937
class check,load,compile,prep,forecast,extract,plot step
import torch, numpy as np, pandas as pd, timesfm
# 1. System check (run once)
# python scripts/check_system.py
# 2-3. Load and compile
torch.set_float32_matmul_precision("high")
model = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch"
)
model.compile(timesfm.ForecastConfig(
max_context=512, max_horizon=52, normalize_inputs=True,
use_continuous_quantile_head=True, fix_quantile_crossing=True,
))
# 4. Prepare data
df = pd.read_csv("weekly_demand.csv", parse_dates=["week"])
values = df["demand"].values.astype(np.float32)
# 5. Forecast
point, quantiles = model.forecast(horizon=52, inputs=[values])
# 6. Extract prediction intervals
forecast_df = pd.DataFrame({
"forecast": point[0],
"lower_80": quantiles[0, :, 1],
"upper_80": quantiles[0, :, 9],
})
# 7. Plot
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(values[-104:], label="Historical")
x_fc = range(len(values[-104:]), len(values[-104:]) + 52)
ax.plot(x_fc, forecast_df["forecast"], label="Forecast", color="tab:orange")
ax.fill_between(x_fc, forecast_df["lower_80"], forecast_df["upper_80"],
alpha=0.2, color="tab:orange", label="80% PI")
ax.legend()
ax.set_title("52-Week Demand Forecast")
plt.tight_layout()
plt.savefig("forecast.png", dpi=150)
print("Saved forecast.png")
Workflow 2: Batch Forecasting (Many Series)
import pandas as pd, numpy as np
# Load wide-format CSV (one column per series)
df = pd.read_csv("all_stores.csv", parse_dates=["date"], index_col="date")
inputs = [df[col].dropna().values.astype(np.float32) for col in df.columns]
# Forecast all series at once (batched internally)
point, quantiles = model.forecast(horizon=30, inputs=inputs)
# Collect results
results = {}
for i, col in enumerate(df.columns):
results[col] = {
"forecast": point[i].tolist(),
"lower_80": quantiles[i, :, 1].tolist(),
"upper_80": quantiles[i, :, 9].tolist(),
}
# Export
import json
with open("batch_forecasts.json", "w") as f:
json.dump(results, f, indent=2)
print(f"Forecasted {len(results)} series → batch_forecasts.json")
Workflow 3: Evaluate Forecast Accuracy
import numpy as np
# Hold out the last H points for evaluation
H = 24
train = values[:-H]
actual = values[-H:]
point, quantiles = model.forecast(horizon=H, inputs=[train])
pred = point[0]
# Metrics
mae =
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [zLanqing](https://github.com/zLanqing)
- **Source:** [zLanqing/codex-claude-academic-skills](https://github.com/zLanqing/codex-claude-academic-skills)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.