Exogenous variables (exog) are covariates: extra inputs known over the forecast horizon. Iteration 1 supports future-known dynamic covariates only.
df:unique_id,ds,y, plus exog columns. For history, exog must cover the observed period. Forcross_validation(), also include exog (andy) through the end of each fold so horizon covariates are read fromdf(no separate horizon frame).X_df:unique_id,ds, exog columns for the nexthsteps (noy). Used byforecast()only.- Alias:
futr_df= same asX_dfonforecast(). futr_exog_list(optional): exog column names only (notunique_id,ds, ory). Onforecast(), infer fromX_dfif omitted. Oncross_validation(), infer from non-target columns indfif omitted.
| Value | Behavior when horizon exog is provided |
|---|---|
"auto" (default) |
Use native exog when the checkpoint supports it; otherwise raise |
False |
Ignore X_df / futr_exog_list; univariate forecast (also in CV) |
When a model does not support native exog and you pass X_df, the library logs a
warning and raises ValueError. FoundationForecast checks every member model
before calling forecast() or cross_validation() so a fallback_model is not used
instead of that error. For mixed runs, set exog_strategy=False on models that do not
support native exog so they ignore horizon exog.
FoundationForecast uses supports_native_futr_exog() on the forecaster instance
(usually a function of repo_id or API model id). Only these paths accept
X_df / CV exog under the default "auto" strategy.
| Wrapper | repo_id / id pattern |
Native futr exog | Notes |
|---|---|---|---|
| Chronos | contains chronos-2 (case-insensitive), e.g. amazon/chronos-2 |
Yes | Other Chronos checkpoints → error with X_df |
| FlowState | any | No | Use exog_strategy=False in multi-model runs |
| Moirai | any | No | Use exog_strategy=False in multi-model runs |
| PatchTST-FM | any | No | Use exog_strategy=False in multi-model runs |
| Sundial | any | No | Use exog_strategy=False in multi-model runs |
| Tabby | any | No | Use exog_strategy=False in multi-model runs |
| TabPFN | any | No | Use exog_strategy=False in multi-model runs |
| T0 | theforecastingcompany/t0-alpha, theforecastingcompany/t0-beta, theforecastingcompany/t0-gamma |
Yes | future_covariates in tfc-t0 |
| Tafsut | any | No | Use exog_strategy=False in multi-model runs |
| TiRex | checkpoint TiRex-2 or TiRex-2-*, e.g. NX-AI/TiRex-2 |
Yes | TiRex 1.0 (e.g. NX-AI/TiRex) → error with X_df |
| TimeH2O | h2oai/timeh2o-v1 (any repo_id without tiny) |
Yes | future_covariates in h2ofm; h2oai/timeh2o-v1-tiny → error with X_df |
| TimeGPT | any Nixtla model= id (e.g. timegpt-1, timegpt-2) |
Yes | Hosted API via X_df |
| TimesFM | contains 3.0, e.g. google/timesfm-3.0-pytorch |
Yes | 1.0, 2.0, 2.5 → error with X_df |
| Toto | any | No | Use exog_strategy=False in multi-model runs |
Local checkpoint paths follow the same rules as Hugging Face repo_id strings passed to the
wrapper. For cross_validation(), pass exog in df through the holdout window; the
same native rules apply per checkpoint.
import pandas as pd
from foundationforecast.models import Chronos, Tafsut
from foundationforecast import FoundationForecast
df = pd.read_parquet(
"https://timecopilot.s3.amazonaws.com/public/data/electricity_price/train.parquet"
)
X_df = pd.read_parquet(
"https://timecopilot.s3.amazonaws.com/public/data/electricity_price/futr_exog.parquet"
)
# Panel of fev-bench EPF markets (BE, DE, FR, NP, PJM); covariates unified as ex_1, ex_2
model = Chronos(repo_id="amazon/chronos-2", alias="Chronos-2")
fcst = model.forecast(df=df, h=24, X_df=X_df)
# Mixed FoundationForecast: native model + univariate models ignoring X_df
ff = FoundationForecast(
models=[
Chronos(repo_id="amazon/chronos-2", alias="Chronos-2"),
Tafsut(alias="Tafsut", exog_strategy=False),
]
)
fcst_panel = ff.forecast(df=df, h=24, X_df=X_df)
# Cross-validation: exog columns in `df` through the holdout window (no X_df)
cv = model.cross_validation(df=df, h=24)See docs/examples/exogenous-variables.ipynb for more models.