HW_FORECAST
This function fits Holt-Winters exponential smoothing with configurable trend and seasonality and returns point forecasts.
The model combines level, trend, and seasonal recursions, and can be additive or multiplicative depending on the selected components.
Forecasts follow the estimated structural decomposition over the specified horizon.
Excel Usage
=HW_FORECAST(endog, steps, trend, seasonal, seasonal_periods, damped_trend, initialization_method)
endog(list[list], required): Time-series observations as a 2D range (data points).steps(int, optional, default: 1): Number of future periods to forecast (periods).trend(str, optional, default: “none”): Trend component type add, mul, additive, multiplicative, or none (option).seasonal(str, optional, default: “none”): Seasonal component type add, mul, additive, multiplicative, or none (option).seasonal_periods(int, optional, default: 0): Number of periods in one full seasonal cycle (periods).damped_trend(bool, optional, default: false): Whether to damp the trend component (true/false).initialization_method(str, optional, default: “estimated”): Initialization method such as estimated, heuristic, known, or legacy-heuristic (option).
Returns (list[list]): Row vector containing forecasted values for the requested forecast horizon.
Example 1: Holt-Winters used as level-only smoothing
Inputs:
| endog | trend | seasonal | steps | |||||
|---|---|---|---|---|---|---|---|---|
| 15 | 16 | 17 | 18 | 19 | 20 | none | none | 1 |
Excel formula:
=HW_FORECAST({15,16,17,18,19,20}, "none", "none", 1)
Expected output:
20
Example 2: Holt-Winters with additive trend only
Inputs:
| endog | trend | seasonal | steps | ||||||
|---|---|---|---|---|---|---|---|---|---|
| 5 | 6 | 8 | 9 | 11 | 13 | 14 | add | none | 2 |
Excel formula:
=HW_FORECAST({5,6,8,9,11,13,14}, "add", "none", 2)
Expected output:
| Result | |
|---|---|
| 15.7145 | 17.286 |
Example 3: Holt-Winters with additive seasonality
Inputs:
| endog | trend | seasonal | seasonal_periods | steps | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 10 | 12 | 14 | 13 | 11 | 13 | 15 | 14 | 12 | 14 | 16 | 15 | add | add | 4 | 1 |
Excel formula:
=HW_FORECAST({10,12,14,13,11,13,15,14,12,14,16,15}, "add", "add", 4, 1)
Expected output:
13
Example 4: Holt-Winters with damped additive trend
Inputs:
| endog | trend | seasonal | damped_trend | steps | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 22 | 24 | 27 | 30 | 33 | 35 | 37 | 39 | add | none | true | 1 |
Excel formula:
=HW_FORECAST({22,24,27,30,33,35,37,39}, "add", "none", TRUE, 1)
Expected output:
41.0652
Python Code
import numpy as np
from statsmodels.tsa.holtwinters import ExponentialSmoothing as sm_ExponentialSmoothing
def hw_forecast(endog, steps=1, trend='none', seasonal='none', seasonal_periods=0, damped_trend=False, initialization_method='estimated'):
"""
Fit Holt-Winters exponential smoothing and return forecasts.
See: https://www.statsmodels.org/stable/generated/statsmodels.tsa.holtwinters.ExponentialSmoothing.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).
steps (int, optional): Number of future periods to forecast (periods). Default is 1.
trend (str, optional): Trend component type add, mul, additive, multiplicative, or none (option). Default is 'none'.
seasonal (str, optional): Seasonal component type add, mul, additive, multiplicative, or none (option). Default is 'none'.
seasonal_periods (int, optional): Number of periods in one full seasonal cycle (periods). Default is 0.
damped_trend (bool, optional): Whether to damp the trend component (true/false). Default is False.
initialization_method (str, optional): Initialization method such as estimated, heuristic, known, or legacy-heuristic (option). Default is 'estimated'.
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
def normalize_component(value):
if value is None:
return None
text = str(value).strip().lower()
if text in ("none", "n", ""):
return None
return text
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) < 4:
return "Error: endog must contain at least 4 numeric values"
if steps < 1:
return "Error: steps must be at least 1"
trend_value = normalize_component(trend)
seasonal_value = normalize_component(seasonal)
seasonal_periods_value = None if int(seasonal_periods) <= 0 else int(seasonal_periods)
model = sm_ExponentialSmoothing(
series,
trend=trend_value,
damped_trend=bool(damped_trend),
seasonal=seasonal_value,
seasonal_periods=seasonal_periods_value,
initialization_method=initialization_method
)
fitted = model.fit()
forecast = np.asarray(fitted.forecast(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).
Number of future periods to forecast (periods).
Trend component type add, mul, additive, multiplicative, or none (option).
Seasonal component type add, mul, additive, multiplicative, or none (option).
Number of periods in one full seasonal cycle (periods).
Whether to damp the trend component (true/false).
Initialization method such as estimated, heuristic, known, or legacy-heuristic (option).