util::fast_ewma
Adjusted exponential smoothing
Section titled “Adjusted exponential smoothing”ewma turns an oldest-first numeric sequence into an equally long sequence of
weighted means. Use it to smooth a feature or threshold when recent observations
should count more than older ones. window is a span, not a rolling cutoff:
with span 3, each older observation receives half the weight of the next one.
No timestamps are accepted, so decay is per observation, even across time gaps.
The implementation in fast_ewma.rs normalizes by the weights available so far. For and ,
Equivalently, update a numerator and denominator , starting with , and return . This is adjusted EWMA; applying directly would give different early values.
For [3, 6, 12] at span 3, the final numerator is
and the denominator is , giving 9.
The intermediate value is .
python3 docs-site/scripts/figures/utility_data_figures.py.Runnable Python example
Section titled “Runnable Python example”import mathfrom openquant import fast_ewma
values = [3.0, 6.0, 12.0]smoothed = fast_ewma.ewma(values, window=3)assert smoothed == [3.0, 5.0, 9.0]assert fast_ewma.ewma(values, window=1) == valuesassert fast_ewma.ewma([], window=3) == []missing = fast_ewma.ewma([3.0, float("nan"), 12.0], window=3)print(smoothed)print([math.isnan(x) for x in missing])try: fast_ewma.ewma(values, window=0)except ValueError: print("zero span rejected")[3.0, 5.0, 9.0][False, True, True]zero span rejectedThe numerical assertions come from the weighted fractions above, not a fitted reference series. The missing-value example illustrates a deliberate limit: a NaN contaminates every later output; this is not pandas’ default skip-missing behavior. Clean or explicitly segment the input before smoothing.
Rust equivalent
Section titled “Rust equivalent”use openquant::util::fast_ewma::ewma;
let smoothed = ewma(&[3.0, 6.0, 12.0], 3)?;assert_eq!(smoothed, vec![3.0, 5.0, 9.0]);assert!(ewma(&[], 3)?.is_empty());assert!(ewma(&[3.0], 0).is_err());Input and output contract
Section titled “Input and output contract”| Input or case | Behavior |
|---|---|
arr in Python / arr_in in Rust | Numeric observations, oldest first |
Positive window | Span; larger spans give slower decay |
| Empty sequence | Empty output, provided the span is positive |
| Span 1 | Returns finite inputs unchanged |
| Span 0 | Python ValueError; Rust InputError::OutOfRange |
| Nonfinite values | Not validated; NaNs propagate |
Smoothing does not turn a nonstationary feature into a stationary one, and a span is not a forecast horizon. Choose the observation frequency and span as part of the feature definition, then evaluate them in the downstream workflow.
Sources and related modules
Section titled “Sources and related modules”- Rust implementation and doctests: normalized weights, span validation and empty-input behavior.
- Python binding contract: argument names, return shape and NaN behavior.
- Volatility estimates dispersion rather than a mean; filters sample events from prices.
API reference
Section titled “API reference”Python
Section titled “Python”Signatures, parameters, return values and errors for every function: openquant.fast_ewma.
fast_ewma.ewma— Bias-corrected exponentially weighted moving average with span `window`.
Rustdoc for this commit, with every public item of openquant::util::fast_ewma (after a crates.io release the same pages are on docs.rs):