> *John Spencer designed 15 weights that zero out quarterly and quintile seasonality from economic data. Eighty years later, statisticians still reach for them when they need a quick seasonal adjustment that does not require the German engineering of X-13ARIMA.*
SP15 is a fixed-coefficient symmetric FIR filter with 15 weights: $[-3, -6, -5, 3, 21, 46, 67, 74, 67, 46, 21, 3, -5, -6, -3]$ divided by 320. The weights were designed by John Spencer to have zero frequency response at periods 4 and 5 (frequencies $2\pi/4$ and $2\pi/5$), making the filter effective at removing quarterly and quintile seasonal components from economic time series. The negative edge weights provide bandpass-like characteristics, and the fixed design requires no parameters beyond the source series.
## Historical Context
John Spencer published the 15-point and 21-point weighted moving averages in 1904 for use in actuarial graduation (smoothing mortality tables). The weights were constructed to satisfy two constraints simultaneously: (1) preserve polynomial trends up to degree 3 (cubic), and (2) have zero response at specific seasonal frequencies. The 15-point variant zeros out periods 4 and 5; the 21-point variant zeros out periods 4, 5, and 7.
Spencer's filters predated Henderson's (1916) by twelve years and were widely used in actuarial science and economic statistics before the X-11 method standardized on Henderson filters. The Spencer 15-point filter was the default seasonal adjustment tool at the U.K. Office for National Statistics until the adoption of X-11 in the 1960s. In modern practice, it remains useful as a quick-and-dirty seasonal smoother when full X-13ARIMA decomposition is overkill.
The fixed 15-bar length creates a natural centered lag of 7 bars, which is appropriate for quarterly data (4 observations per year, so a 15-point filter spans nearly 4 quarters). For financial time series, the filter useful for removing intra-week (5-bar) and intra-month patterns from daily data.
## Architecture & Physics
### 1. Fixed Weight Vector
The 15 weights are hardcoded constants, symmetric around the center:
No weight computation is needed; the coefficients are compile-time constants.
### 2. Symmetric Convolution
The symmetric structure allows folded computation: pair the $i$-th and $(14-i)$-th bars (which share the same weight), sum them, then multiply by the weight once. This halves the multiplication count from 15 to 8.
### 3. Negative Edge Weights
Three weights at each edge are negative ($-3, -6, -5$), giving the filter its seasonal-nulling property. The output can exceed the input range when edge bars have extreme values relative to the center.
### 4. Zero-Parameter Design
SP15 takes no period parameter. The filter length is always 15, and the weights are always Spencer's original values. This is both a strength (no tuning required) and a limitation (no adaptation to different data characteristics).
SP15 is a fixed 15-tap FIR filter with hard-coded Spencer weights (sum = 320). At construction, 15 normalized doubles are computed once. Each `Update()` is a pure 15-element dot product.
| Operation | Count | Cost (cycles) | Subtotal |
| :--- | :---: | :---: | :---: |
| Ring buffer push | 1 | 3 | ~3 |
| FIR dot product: 15 FMA | 15 | 4 | ~60 |
| **Total** | **16** | — | **~63 cycles** |
O(1) per bar (N is fixed at 15). The dot product takes ~60 cycles on modern x86. WarmupPeriod = 15. No parameters to validate.
With symmetric folding (8 unique weight pairs), the 15-tap dot product reduces to ~8 FMAs. AVX2 processes 4 output bars per outer iteration. Batch throughput: ~2 cycles per output bar at peak. Unrolled codegen fits entirely in instruction cache.