EMA_LFILTER
This function computes an exponential moving average (EMA) by applying a first-order recursive filter.
With smoothing factor \alpha, the recursion is:
\text{EMA}_t = \alpha x_t + (1-\alpha)\,\text{EMA}_{t-1}
Lower \alpha values produce stronger smoothing, while higher \alpha values react more quickly to new observations.
Excel Usage
=EMA_LFILTER(data, alpha, initial)
data(list[list], required): Time-series observations as a 2D range (data points).alpha(float, optional, default: 0.2): Smoothing factor between 0 and 1 (unitless).initial(float, optional, default: null): Optional initial EMA level used before processing the first observation (value).
Returns (list[list]): Column vector of exponentially smoothed values.
Example 1: EMA with default smoothing factor
Inputs:
| data | ||||
|---|---|---|---|---|
| 10 | 12 | 11 | 13 | 15 |
Excel formula:
=EMA_LFILTER({10,12,11,13,15})
Expected output:
| Result |
|---|
| 2 |
| 4 |
| 5.4 |
| 6.92 |
| 8.536 |
Example 2: EMA with faster response smoothing
Inputs:
| data | alpha | |||
|---|---|---|---|---|
| 5 | 8 | 7 | 10 | 0.6 |
Excel formula:
=EMA_LFILTER({5,8,7,10}, 0.6)
Expected output:
| Result |
|---|
| 3 |
| 6 |
| 6.6 |
| 8.64 |
Example 3: EMA with explicit initial level
Inputs:
| data | alpha | initial | |||
|---|---|---|---|---|---|
| 20 | 19 | 21 | 22 | 0.3 | 18 |
Excel formula:
=EMA_LFILTER({20,19,21,22}, 0.3, 18)
Expected output:
| Result |
|---|
| 18.6 |
| 18.72 |
| 19.404 |
| 20.1828 |
Example 4: Scalar input EMA
Inputs:
| data | alpha |
|---|---|
| 9 | 0.5 |
Excel formula:
=EMA_LFILTER(9, 0.5)
Expected output:
4.5
Python Code
import numpy as np
from scipy.signal import lfilter as sp_lfilter
def ema_lfilter(data, alpha=0.2, initial=None):
"""
Compute an exponential moving average using recursive linear filtering.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.lfilter.html
This example function is provided as-is without any representation of accuracy.
Args:
data (list[list]): Time-series observations as a 2D range (data points).
alpha (float, optional): Smoothing factor between 0 and 1 (unitless). Default is 0.2.
initial (float, optional): Optional initial EMA level used before processing the first observation (value). Default is None.
Returns:
list[list]: Column vector of exponentially smoothed values.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
data = to2d(data)
if not isinstance(data, list) or not all(isinstance(row, list) for row in data):
return "Error: Invalid input - data must be a 2D list"
if alpha <= 0 or alpha > 1:
return "Error: alpha must be greater than 0 and less than or equal to 1"
series = []
for row in data:
for item in row:
try:
series.append(float(item))
except (TypeError, ValueError):
continue
if not series:
return "Error: data must contain at least one numeric value"
b = [float(alpha)]
a = [1.0, -(1.0 - float(alpha))]
arr = np.asarray(series, dtype=float)
if initial is None:
ema = sp_lfilter(b, a, arr)
else:
zi = [(1.0 - float(alpha)) * float(initial)]
ema, _ = sp_lfilter(b, a, arr, zi=zi)
return [[float(x)] for x in np.asarray(ema, dtype=float).tolist()]
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Time-series observations as a 2D range (data points).
Smoothing factor between 0 and 1 (unitless).
Optional initial EMA level used before processing the first observation (value).