Cumulative Advance/Decline Line
Recompute History Without Looking Ahead
Install and import#
npm install fintech-algorithmsimport { calculateCumulativeAdvanceDeclineLine } from "fintech-algorithms/market-breadth-and-internals/advance-decline-breadth/cumulative-advance-decline-line";Signature#
calculateCumulativeAdvanceDeclineLine(contract, events, knowledgeCutoff)Runs net advances into a cumulative line. Its level is arbitrary; the information is in the shape, and specifically in divergence — when the index makes a high the line does not, participation is narrowing.
Parameters#
| Name | Type | Notes |
|---|---|---|
contract | LineContract | Series identity and the seed the accumulation starts from. The seed only shifts the level, never the shape. |
events | BreadthEvent[] | Session events including revisions and supersessions, each with an ingest sequence. |
knowledgeCutoff | string | Point-in-time bound. Revisions arriving after the cutoff are ignored rather than applied, so the series is exactly what was computable at that moment. Breadth data is revised routinely, and a cumulative line silently rebuilt from revised inputs is not the line anyone traded. |
Returns#
{ status, reasons, knowledge_cutoff, points, final_value, causal_prefix_diagnostic, missing_sessions, … }
The line plus a causal-prefix diagnostic and the sessions that were missing — a gap in a cumulative series propagates forward forever, so it must be visible.
Errors#
- When events are missing an ingest sequence needed to order them — reported in reasons rather than thrown
Complexity: time O(events),
space O(sessions).
Worked example#
verified This is the worked example published in the article, replayed by the test suite on every run. The output cannot drift.
Input#
{
"metric": "cumulative_issue_count_advance_decline_line",
"series_id": "SYNTH-AD",
"continuity_id": "SYNTH-CONTINUITY",
"venue_id": "SYNTH-X",
"universe_id": "SYNTH-5",
"calendar_id": "SYNTH-CAL",
"session_type": "regular",
"comparison_basis": "comparable-prior-close",
"seed": 0,
"seed_lineage_id": "SEED-0",
"seed_effective_at": "2026-01-04T21:00:00Z",
"seed_available_at": "2026-01-04T21:05:00Z",
"expected_sessions": [
{
"session_sequence": 1,
"session_date": "2026-01-05"
},
{
"session_sequence": 2,
"session_date": "2026-01-06"
}
]
}[
{
"event_id": "AD-1",
"ingest_sequence": 1,
"revision_number": 1,
"supersedes_event_id": null,
"action": "upsert",
"session_sequence": 1,
"session_date": "2026-01-05",
"effective_at": "2026-01-05T21:00:00Z",
"available_at": "2026-01-05T21:05:00Z",
"series_id": "SYNTH-AD",
"continuity_id": "SYNTH-CONTINUITY",
"venue_id": "SYNTH-X",
"universe_id": "SYNTH-5",
"calendar_id": "SYNTH-CAL"
},
{
"event_id": "AD-2",
"ingest_sequence": 2,
"revision_number": 1,
"supersedes_event_id": null,
"action": "upsert",
"session_sequence": 2,
"session_date": "2026-01-06",
"effective_at": "2026-01-06T21:00:00Z",
"available_at": "2026-01-06T21:05:00Z",
"series_id": "SYNTH-AD",
"continuity_id": "SYNTH-CONTINUITY",
"venue_id": "SYNTH-X",
"universe_id": "SYNTH-5",
"calendar_id": "SYNTH-CAL"
}
]"2026-01-06T22:00:00Z"Call#
calculateCumulativeAdvanceDeclineLine(contract, events, knowledgeCutoff)Returns#
object with 6 fields: status, reasons, final_value, contains_provisional, ignored_future_event_count, points
{
"status": "resolved",
"reasons": [],
"final_value": 1,
"contains_provisional": false,
"ignored_future_event_count": 0,
"points": {
"0": {
"session_sequence": 1,
"net_advances": 2,
"cumulative_line": 2
},
"1": {
"session_sequence": 2,
"net_advances": -1,
"cumulative_line": 1
}
}
}Diagrams#
Calculation flow#
Revision lineage and suffix recomputation
flowchart LR
A["Session k revision 1"] --> B["Revision 2 names revision 1 as parent"]
B --> C{"Revision 2 available by cutoff?"}
C -- "No" --> D["Keep revision 1"]
C -- "Yes" --> E["Select revision 2"]
E --> F["Recompute session k"]
F --> G["Recompute every later session"]
G --> H["Publish new resolved suffix"]
Causal recurrence and publication flow
flowchart TD
A["Continuity contract and knowledge cutoff"] --> B["Parse availability time"]
B --> C{"Event known by cutoff?"}
C -- "No" --> D["Ignore future event"]
C -- "Yes" --> E["Validate visible order, identity, and daily evidence"]
E --> F["Select one contiguous revision chain per session"]
F --> G{"All expected sessions ready and final?"}
G -- "No" --> H["Suppress main line and label diagnostic prefix"]
G -- "Yes" --> I["Add Net Advances in declared calendar order"]
I --> J["Publish resolved points and final value"]
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#
- Nasdaq Trader Daily Market Files
- Nasdaq Trader Daily Market Summary Definitions
- Fidelity advance/decline education
- Nasdaq A-D glossary
- Evidence boundary