Zweig Breadth Thrust
Install and import#
npm install fintech-algorithmsimport { calculate } from "fintech-algorithms/market-breadth-and-internals/thrust-and-pressure/zweig-breadth-thrust";Signature#
calculate(rows, emaLength, lowThreshold, highThreshold, maxSessions)Detects the rare initiation signal: the advance ratio moving from below a low threshold to above a high one inside a bounded number of sessions. It fires a handful of times in a generation, which is the point — and also why it cannot be validated on a short sample.
Parameters#
| Name | Type | Notes |
|---|---|---|
rows | Row[] | Sessions carrying advances and declines. 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. |
emaLength | number | EMA length applied to the advance ratio. Zweig's original is 10. min: 1 · integer: true |
lowThreshold | number | The ratio the EMA must fall below to arm the signal. Conventionally 0.40. min: 0 |
highThreshold | number | The ratio it must then exceed. Conventionally 0.615. min: 0 |
maxSessions | number | Maximum sessions permitted between the two crossings; beyond it the move is not a thrust. min: 1 · integer: true |
Returns#
{ status, trigger_date, ema, sessions, series }
The trigger date if one occurred, with the EMA path and session count so a near-miss can be seen rather than merely absent.
Errors#
- When lowThreshold ≥ highThreshold — throws
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#
[
{
"session_date": "2026-01-05",
"advances": 520,
"declines": 480,
"ready": true
},
{
"session_date": "2026-01-06",
"advances": 500,
"declines": 500,
"ready": true
},
{
"session_date": "2026-01-07",
"advances": 480,
"declines": 520,
"ready": true
}
]Showing 3 of 24 elements.
100.40.61510Call#
calculate(rows, emaLength, lowThreshold, highThreshold, maxSessions)Returns#
object with 5 fields: status, trigger_date, ema, sessions, series
{
"status": "thrust",
"trigger_date": "2026-01-28",
"ema": 0.6648021169863199,
"sessions": 6,
"series": [
{
"date": "2026-01-05",
"ratio": 0.52,
"ema": 0.52,
"state": "idle"
},
{
"date": "2026-01-06",
"ratio": 0.5,
"ema": 0.5163636363636364,
"state": "idle"
},
{
"date": "2026-01-07",
"ratio": 0.48,
"ema": 0.5097520661157025,
"state": "idle"
}
]
}Diagrams#
Calculation flow#
Calculation Flow — Zweig Breadth Thrust
flowchart LR
A["Ordered A and D counts"] --> B["Breadth ratio A/(A+D)"]
B --> C["Update EMA10"]
C --> D{"EMA < 0.400?"}
D -->|"Yes"| E["Arm or refresh clock"]
D -->|"No"| F{"Armed and EMA > 0.615?"}
E --> G["Advance session age"]
G --> F
F -->|"Yes, age ≤ 10"| H["Publish thrust now"]
F -->|"No, age > 10"| I["Expire"]
F -->|"No, age ≤ 10"| G
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 Indicators — StockCharts ChartSchool
- Advance Decline Ratio Indicators, Chapter 5 — Greg Morris, StockCharts
- Historical-example decision