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

Ease of Movement

Install and import#

bash
npm install fintech-algorithms
ts
import { easeOfMovement } from "fintech-algorithms/technical-indicators/volume-indicators/ease-of-movement";

Signature#

easeOfMovement(input)

Divides the typical-price change by a box ratio built from scaled volume over the bar range, then smooths that raw reading with a simple moving average.

Parameters#

NameTypeNotes
inputTopicInputbars needs timestamp, high, low, close and volume. From parameters this topic reads volume_scale (default 1000000, a finite number of at least 0.000001) and period (default 14, an integer of at least 2).

Returns#

TopicResult

series holds raw, the unsmoothed reading, and value, its simple moving average over period. latest carries the last element of each. raw is null on the first bar and on any bar whose high equals its low or whose volume is 0; value needs a full window of non-null raw, so it starts later than raw. Both warm-ups are described below.

Warm-up#

The first 1 bar for `raw`; `period` bars for `value` (index 14 with the defaults) positions are null. ready_at is 1, driven by raw. Because a null inside the window restarts the average, any flat or zero-volume bar pushes value out by a further period bars.

Errors#

  • When volume_scale is below 0.000001 or not a finite number — throws Error
  • When period is not an integer of at least 2 — throws Error
  • When a bar carries a negative volume — throws Error

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

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#

input
{
  "bars": [
    {
      "timestamp": "2024-01-02",
      "basis": "synthetic-unadjusted",
      "open": 100,
      "high": 101.45,
      "low": 98.695,
      "close": 100,
      "volume": 750000,
      "benchmark": 200
    },
    {
      "timestamp": "2024-01-03",
      "basis": "synthetic-unadjusted",
      "open": 101.49111452,
      "high": 103.38381693,
      "low": 100.05480022,
      "close": 101.78791214,
      "volume": 795117,
      "benchmark": 200.56326135
    },
    {
      "timestamp": "2024-01-04",
      "basis": "synthetic-unadjusted",
      "open": 102.45519048,
      "high": 104.6701838,
      "low": 100.91147007,
      "close": 102.9549389,
      "volume": 840234,
      "benchmark": 201.11020913
    }
  ],
  "parameters": {}
}

Call#

easeOfMovement(input)

Returns#

object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …

{
  "topic_id": "D07-F05-A12",
  "title": "Ease of Movement",
  "state": "calculated",
  "ready": true,
  "ready_at": 1,
  "series": {
    "raw": [
      null,
      7.09182670339273,
      4.935760375263474,
      1.1777185136470167,
      -1.4745208573506723,
      -1.699726591438122
    ],
    "value": [null, null, null, null, null, null]
  },
  "latest": {
    "raw": -3.4562255141040934,
    "value": -0.7167616272036208
  },
  "parameters": {},
  "diagnostics": {
    "causal": true,
    "input_count": 96
  }
}

Diagrams#

Ease of Movement — article hero
Ease of Movement — concept map
Ease of Movement — decision comparison
Ease of Movement — worked example

Calculation flow#

Ease of Movement calculation flow
flowchart LR
    A["basis-consistent OHLCV observations with venue/session cov"] --> B["Validate order, basis, and finite values"]
    B --> C["Apply the selected Ease of Movement convention"]
    C --> D["Emit value, readiness, and diagnostics"]
    D --> E["Interpret descriptively; test outcomes separately"]
    B -->|invalid or insufficient| X["Withhold output with a reason"]
Ease of Movement readiness and evidence states
stateDiagram-v2
    [*] --> Waiting
    Waiting --> Ready: enough valid causal observations
    Waiting --> Rejected: malformed or unsupported input
    Ready --> Calculated: selected formula applied
    Calculated --> Interpreted: diagnostic and limitation retained
    Interpreted --> Ready: next observation arrives
    Rejected --> Waiting: corrected input and deterministic reset

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#

  • TA-Lib function groups — see linked primary or authoritative record
  • TA-Lib C/C++ API — see linked primary or authoritative record
  • TA-Lib maintained source — see linked primary or authoritative record
  • Evidence decision
  • Level 1 evidence map

The rest of the Volume Indicators family#