Breadth-Divergence Detector
Install and import#
npm install fintech-algorithmsimport { 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#
| Name | Type | Notes |
|---|---|---|
rows | Row[] | 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. |
left | number | Left comparison offset in sessions. min: 1 · integer: true |
right | number | Right comparison offset in sessions. min: 0 · integer: true |
minPriceChange | number | Minimum index move required before a divergence is considered; filters noise. min: 0 |
minBreadthSeparation | number | Minimum breadth move required, expressed in the units breadthScale implies.min: 0 |
breadthScale | number | Scaling 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#
[
{
"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.
220.010.051000Call#
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#
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.
References#
- Claim-to-source map
- Advance/Decline Indicator — Fidelity
- Advance-Decline Volume Line — StockCharts ChartSchool
- Advance-Decline Indicators — StockCharts ChartSchool
- Historical-example decision