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).