STL — Seasonal-Trend Decomposition Using LOESS

Separate a regularly spaced series into trend, a single seasonal pattern that can evolve over time, and a remainder. The default output is a compact slideshow of the original series, trend, seasonal component, remainder and diagnostics.

Syntax

STL(series,period)
STL(series,period,seasonalWindow)
STL(series,period,seasonalWindow,trendWindow)
STL(series,period,seasonalWindow,trendWindow,robust)

Example

Employment=SERIES_SINCE(PAYNSA,20000101)
D=STL(Employment,12,7,23,1)
D

PAYNSA supplies monthly non-seasonally-adjusted payroll employment. The example uses robust fitting so exceptional observations need not dominate the trend and seasonal smoothers.

Trend=EXTRACT(D,"trend")
Seasonal=EXTRACT(D,"seasonal")
Adjusted=EXTRACT(D,"adjusted")
Remainder=EXTRACT(D,"remainder")
LINE_CHART(Adjusted)

Components and extracts

Observed = Trend + Seasonal + Remainder
Adjusted = Observed - Seasonal
Fitted = Trend + Seasonal

observed/original, trend, seasonal, remainder/residuals, adjusted/seasonally_adjusted, fitted and weights/robustness_weights return ordinary SeriesOperator results retaining input dates and frequency. Component units match the input; weights are an index from zero to one. Extracted series are fresh copies.

slideshow returns the presentation. observed_chart, trend_chart, seasonal_chart, remainder_chart and adjusted_chart return individual D3 charts. summary/diagnostics describes settings, reconstruction accuracy and interpretation. Numeric extracts include n, period, seasonal_window, trend_window, lowpass_window, robust, seasonal_strength, trend_strength and reconstruction_error.

Input spacing and missing data

Requires n > 2*period. Monthly, quarterly, semiannual and annual series are checked by calendar-month intervals, accommodating unequal month lengths. Daily and weekly data are checked by calendar-day intervals, accommodating daylight-saving changes. Hourly or other fixed-step data can use constant elapsed timestamps. Unknown frequency labels are checked for a regular monthly or fixed-timestamp grid.

Dates must be strictly increasing. Missing periods, duplicate dates and nonfinite values are rejected. Complete or aggregate the input deliberately before decomposition; no implicit dropping or interpolation is performed. Calendar-daily market prices with weekend or holiday gaps are rejected. A daily period 365 is a 365-observation cycle, not leap-year-aware annual seasonality. Monthly ecological aggregates are a useful first application.

Method and interpretation

Uses ServiceNow stl-decomp-4j 1.0.5, a Java port of the original STL algorithm. Seasonal LOESS degree is 0; trend and low-pass degrees are 1; all interpolation jumps are 1. Low-pass span is the smallest odd integer at least as large as period. Non-robust fitting uses 2 inner iterations and 0 outer iterations; robust fitting uses 1 inner and 15 outer iterations.

Seasonal strength is max(0,1−Var(remainder)/Var(seasonal+remainder)); trend strength is analogous. These are descriptive measures from 0 to 1, not hypothesis tests. Numerically constant denominators give zero. Robust weights indicate influence, not formal outlier probabilities. Nearly exact fits can cause numerically degenerate robustness weights; robust mode does not guarantee successful isolation of every anomalous observation.

The decomposition is additive and supports one seasonal period. It is not a forecast or a claim that the remainder is white noise. Smooths use surrounding data, so this is not a real-time causal filter; components, especially endpoints, can change as observations are added. For seasonality proportional to the level, a log transform of strictly positive values can be useful. Components from logged inputs remain in log units.

STL results depend on window settings and are not interchangeable with an official statistical agency's seasonal adjustment. Exact agreement with R or another implementation also requires matching all algorithm settings.

Available extracts

Save the command result in a variable, then use EXTRACT(result, "key"). Availability can depend on the input form and fitted model.

In indexed patterns such as beta:n, replace n with the required index.