fintech-algorithms

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

executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.

Input

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

Call

calculateEma(values, span)

Returns

array of 6 nulls

[
  null,
  null,
  11.666666666666666,
  13.333333333333332,
  13.666666666666666,
  15.833333333333332
]

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