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

Breadth-Divergence Detector

Install and import#

bash
npm install fintech-algorithms
ts
import { calculate } from "fintech-algorithms/market-breadth-and-internals/thrust-and-pressure/breadth-divergence-detector";

Signature#

calculate(rows, left, right, minPriceChange, minBreadthSeparation, breadthScale)

Flags sessions where the index and a breadth measure move meaningfully in opposite directions — the classic warning that an advance is being carried by fewer and fewer names.

Parameters#

NameTypeNotes
rowsRow[]Sessions carrying an index level and a breadth value. Rows carry a ready flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.
leftnumberLeft comparison offset in sessions.
min: 1 · integer: true
rightnumberRight comparison offset in sessions.
min: 0 · integer: true
minPriceChangenumberMinimum index move required before a divergence is considered; filters noise.
min: 0
minBreadthSeparationnumberMinimum breadth move required, expressed in the units breadthScale implies.
min: 0
breadthScalenumberScaling applied to the breadth series before comparison. **Note:** the published fixture and this implementation currently disagree on the unit of the resulting breadth_separation — the fixture states a ratio, the implementation returns a scaled value. See the article before relying on an absolute threshold.
min: 0

Returns#

{ status, events }

The divergence events detected, each naming the sessions compared and the separation measured.

Errors#

  • When left ≤ right, making the comparison window invalid — throws

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

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#

rows
[
  {
    "session_date": "2026-01-05",
    "index_level": 100,
    "breadth_value": 500,
    "ready": true
  },
  {
    "session_date": "2026-01-06",
    "index_level": 101,
    "breadth_value": 520,
    "ready": true
  },
  {
    "session_date": "2026-01-07",
    "index_level": 102,
    "breadth_value": 540,
    "ready": true
  }
]

Showing 3 of 36 elements.

left
2
right
2
minPriceChange
0.01
minBreadthSeparation
0.05
breadthScale
1000

Call#

calculate(rows, left, right, minPriceChange, minBreadthSeparation, breadthScale)

Returns#

object with 2 fields: status, events

{
  "status": "bearish",
  "events": [
    {
      "status": "bearish",
      "first_pivot_date": "2026-01-19",
      "second_pivot_date": "2026-02-05",
      "confirmation_date": "2026-02-09",
      "price_change": 0.05454545454545454,
      "breadth_separation": -0.13,
      "breadth_scale": 1000
    }
  ]
}

Diagrams#

Breadth-Divergence Detector — decision boundary
Breadth-Divergence Detector — family map

Calculation flow#

Calculation Flow — Breadth-Divergence Detector
flowchart LR
    A["Ordered price and breadth"] --> B["Confirm price pivot after right bars"]
    B --> C["Sample breadth on pivot date"]
    C --> D["Compare adjacent same-kind pivots"]
    D --> E["ΔP = (P2−P1)/P1"]
    D --> F["ΔB = (B2−B1)/breadth_scale"]
    E --> G{"Directional minimums pass?"}
    F --> G
    G -->|"Yes"| H["Publish on second pivot confirmation date"]
    G -->|"No"| I["No event"]

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#

  • Claim-to-source map
  • Advance/Decline Indicator — Fidelity
  • Advance-Decline Volume Line — StockCharts ChartSchool
  • Advance-Decline Indicators — StockCharts ChartSchool
  • Historical-example decision

The rest of the Thrust and Pressure family#