fintech-algorithms
Using a coding agent? Give it the skill: npx skills add IslamBaraka90/Fintech-Algorithms-Library What it does →

Exponential Moving Average (EMA)

Install and import#

bash
npm install fintech-algorithms
ts
import { calculateEma } from "fintech-algorithms/technical-indicators/trend-smoothing/ema";

Signature#

calculateEma(values, span)

Exponentially weighted mean seeded with the simple mean of the first span observations, so the series is reproducible rather than dependent on where the data starts.

Parameters#

NameTypeNotes
values(number | null)[]Observation series in chronological order, oldest first.
nulls: propagate
spannumberSmoothing span; the decay factor is 2 / (span + 1).
min: 1 · integer: true

Returns#

(number | null)[] · length same-as-input

Smoothed series, null until the seed window closes.

Warm-up#

The first span - 1 positions are null. Warm-up positions are null rather than a partial result, so a consumer never mistakes an incomplete window for a real value.

Errors#

  • When span < 1 or is not an integer — throws RangeError

Complexity: time O(n), space O(1).

Worked example#

verified This is the worked example published in the article, replayed by the test suite on every run. The output cannot drift.

Input#

values
[10, 13, 12, 15, 14, 18]
span
3

Call#

calculateEma(values, span)

Returns#

array of 6 nulls

[
  null,
  null,
  11.666666666666666,
  13.333333333333334,
  13.666666666666666,
  15.833333333333334
]

Other exports#

This module also exports alphaFromSpan, calculateAdjustedEma, calculateTimeAwareEma. Every module additionally exports run as an alias of its primary function, and a meta object carrying its catalog id, domain, family, shape and article URL.

Diagrams#

Exponential Moving Average (EMA) — ema path
Exponential Moving Average (EMA) — ema step

Calculation flow#

EMA calculation flow
flowchart LR
    A["Ordered finite observation"] --> B{"Contract and series identity valid?"}
    B -- "No" --> C["Reject without updating state"]
    B -- "Yes" --> D{"EMA seeded?"}
    D -- "No" --> E["Collect valid values"]
    E --> F{"Count equals span?"}
    F -- "No" --> G["Emit warm-up point with null EMA"]
    F -- "Yes" --> H["Seed EMA with simple average"]
    D -- "Yes" --> I["EMA = prior EMA + alpha × current gap"]
    H --> J["Emit ready EMA and provenance"]
    I --> J

How it works#

This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.

Read the article →

References#

  • NIST single exponential smoothing — National Institute of Standards and Technology
  • NIST Dataplot exponential smoothing — National Institute of Standards and Technology
  • pandas exponentially weighted calculations — pandas project
  • StockCharts moving-average methodology — StockCharts.com
  • McClellan EMA calculation — McClellan Financial Publications
  • Evidence and design reconciliation

The rest of the Trend Smoothing family#