SARIMAX_FORECAST
This function fits a seasonal ARIMA model in state-space form and returns point forecasts for future periods.
SARIMAX extends ARIMA by allowing explicit seasonal dynamics and optional exogenous regressors:
\Phi(L^s)\phi(L)(1-L)^d(1-L^s)^D y_t = A(t) + \Theta(L^s)\theta(L)\varepsilon_t
The function supports non-seasonal and seasonal orders and returns forecasts as a row vector.
Excel Usage
=SARIMAX_FORECAST(endog, p, d, q, seasonal_p, seasonal_d, seasonal_q, seasonal_s, steps, trend, enforce_stationarity, enforce_invertibility)
endog(list[list], required): Time-series observations as a 2D range (data points).p(int, optional, default: 1): Non-seasonal autoregressive order (lags).d(int, optional, default: 0): Non-seasonal differencing order (differences).q(int, optional, default: 0): Non-seasonal moving-average order (lags).seasonal_p(int, optional, default: 0): Seasonal autoregressive order (lags).seasonal_d(int, optional, default: 0): Seasonal differencing order (differences).seasonal_q(int, optional, default: 0): Seasonal moving-average order (lags).seasonal_s(int, optional, default: 0): Seasonal period length (periods).steps(int, optional, default: 1): Number of future periods to forecast (periods).trend(str, optional, default: “n”): Deterministic trend specification such as n, c, t, or ct (option).enforce_stationarity(bool, optional, default: true): Whether to enforce stationarity constraints (true/false).enforce_invertibility(bool, optional, default: true): Whether to enforce invertibility constraints (true/false).
Returns (list[list]): Row vector containing forecasted values for the requested forecast horizon.
Example 1: One-step SARIMAX forecast with default order
Inputs:
| endog | steps | |||||||
|---|---|---|---|---|---|---|---|---|
| 30 | 31 | 33 | 32 | 35 | 36 | 37 | 39 | 1 |
Excel formula:
=SARIMAX_FORECAST({30,31,33,32,35,36,37,39}, 1)
Expected output:
38.9517
Example 2: Two-step SARIMAX forecast with differencing
Inputs:
| endog | p | d | q | steps | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 8 | 9 | 11 | 12 | 14 | 15 | 17 | 18 | 1 | 1 | 0 | 2 |
Excel formula:
=SARIMAX_FORECAST({8,9,11,12,14,15,17,18}, 1, 1, 0, 2)
Expected output:
| Result | |
|---|---|
| 18.753 | 19.3201 |
Example 3: SARIMAX with constant trend term
Inputs:
| endog | trend | steps | |||||||
|---|---|---|---|---|---|---|---|---|---|
| 5 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | c | 1 |
Excel formula:
=SARIMAX_FORECAST({5,6,7,9,10,11,13,14}, "c", 1)
Expected output:
13.7427
Example 4: Seasonal SARIMAX with period four
Inputs:
| endog | p | d | q | seasonal_p | seasonal_d | seasonal_q | seasonal_s | steps | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 12 | 14 | 16 | 15 | 13 | 15 | 17 | 16 | 14 | 16 | 18 | 17 | 1 | 0 | 0 | 1 | 0 | 0 | 4 | 1 |
Excel formula:
=SARIMAX_FORECAST({12,14,16,15,13,15,17,16,14,16,18,17}, 1, 0, 0, 1, 0, 0, 4, 1)
Expected output:
14.9982
Python Code
import numpy as np
from statsmodels.tsa.statespace.sarimax import SARIMAX as sm_SARIMAX
def sarimax_forecast(endog, p=1, d=0, q=0, seasonal_p=0, seasonal_d=0, seasonal_q=0, seasonal_s=0, steps=1, trend='n', enforce_stationarity=True, enforce_invertibility=True):
"""
Fit a SARIMAX model and return out-of-sample forecasts.
See: https://www.statsmodels.org/stable/generated/statsmodels.tsa.statespace.sarimax.SARIMAX.html
This example function is provided as-is without any representation of accuracy.
Args:
endog (list[list]): Time-series observations as a 2D range (data points).
p (int, optional): Non-seasonal autoregressive order (lags). Default is 1.
d (int, optional): Non-seasonal differencing order (differences). Default is 0.
q (int, optional): Non-seasonal moving-average order (lags). Default is 0.
seasonal_p (int, optional): Seasonal autoregressive order (lags). Default is 0.
seasonal_d (int, optional): Seasonal differencing order (differences). Default is 0.
seasonal_q (int, optional): Seasonal moving-average order (lags). Default is 0.
seasonal_s (int, optional): Seasonal period length (periods). Default is 0.
steps (int, optional): Number of future periods to forecast (periods). Default is 1.
trend (str, optional): Deterministic trend specification such as n, c, t, or ct (option). Default is 'n'.
enforce_stationarity (bool, optional): Whether to enforce stationarity constraints (true/false). Default is True.
enforce_invertibility (bool, optional): Whether to enforce invertibility constraints (true/false). Default is True.
Returns:
list[list]: Row vector containing forecasted values for the requested forecast horizon.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
endog = to2d(endog)
if not isinstance(endog, list) or not all(isinstance(row, list) for row in endog):
return "Error: Invalid input - endog must be a 2D list"
series = []
for row in endog:
for value in row:
try:
series.append(float(value))
except (TypeError, ValueError):
continue
if len(series) < 3:
return "Error: endog must contain at least 3 numeric values"
if steps < 1:
return "Error: steps must be at least 1"
model = sm_SARIMAX(
series,
order=(int(p), int(d), int(q)),
seasonal_order=(int(seasonal_p), int(seasonal_d), int(seasonal_q), int(seasonal_s)),
trend=trend,
enforce_stationarity=bool(enforce_stationarity),
enforce_invertibility=bool(enforce_invertibility)
)
fitted = model.fit(disp=False)
forecast = np.asarray(fitted.forecast(steps=int(steps)), dtype=float).reshape(1, -1)
return forecast.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Time-series observations as a 2D range (data points).
Non-seasonal autoregressive order (lags).
Non-seasonal differencing order (differences).
Non-seasonal moving-average order (lags).
Seasonal autoregressive order (lags).
Seasonal differencing order (differences).
Seasonal moving-average order (lags).
Seasonal period length (periods).
Number of future periods to forecast (periods).
Deterministic trend specification such as n, c, t, or ct (option).
Whether to enforce stationarity constraints (true/false).
Whether to enforce invertibility constraints (true/false).