fintech-algorithms

Normalized Advance/Decline Line

Cumulative (A-D)/(A+D) Breadth

Install and import

bash
npm install fintech-algorithms
ts
import { calculateNormalizedAdLine } from "fintech-algorithms/market-breadth-and-internals/advance-decline-breadth/normalized-advance-decline-line";

Signature

calculateNormalizedAdLine(records, options)

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

records
[
  {
    "revision": 1,
    "supersedes_revision": null,
    "event_type": "upsert",
    "venue_id": "SYNTH:XNAS",
    "universe_id": "SYNTH:ACTIVE-100",
    "calendar_id": "SYNTH:XNAS-REGULAR",
    "session": "regular",
    "comparison_basis": "official-close-to-comparable-prior-close",
    "corporate_action_policy": "point-in-time-listing-continuity-v1",
    "stable_id_scheme": "synthetic-listing-id-v1",
    "methodology_id": "mover-normalized-ad-line-v1",
    "denominator_policy": "movers",
    "seed": 0,
    "scale": 100
  },
  {
    "revision": 1,
    "supersedes_revision": null,
    "event_type": "upsert",
    "venue_id": "SYNTH:XNAS",
    "universe_id": "SYNTH:ACTIVE-100",
    "calendar_id": "SYNTH:XNAS-REGULAR",
    "session": "regular",
    "comparison_basis": "official-close-to-comparable-prior-close",
    "corporate_action_policy": "point-in-time-listing-continuity-v1",
    "stable_id_scheme": "synthetic-listing-id-v1",
    "methodology_id": "mover-normalized-ad-line-v1",
    "denominator_policy": "movers",
    "seed": 0,
    "scale": 100
  },
  {
    "revision": 1,
    "supersedes_revision": null,
    "event_type": "upsert",
    "venue_id": "SYNTH:XNAS",
    "universe_id": "SYNTH:ACTIVE-100",
    "calendar_id": "SYNTH:XNAS-REGULAR",
    "session": "regular",
    "comparison_basis": "official-close-to-comparable-prior-close",
    "corporate_action_policy": "point-in-time-listing-continuity-v1",
    "stable_id_scheme": "synthetic-listing-id-v1",
    "methodology_id": "mover-normalized-ad-line-v1",
    "denominator_policy": "movers",
    "seed": 0,
    "scale": 100
  }
]

Showing 3 of 20 elements.

options
{
  "cutoff": "2026-02-02T00:00:00Z",
  "expectedStartSequence": 1,
  "expectedEndSequence": 20,
  "initialValue": 0,
  "scale": 100,
  "minimumCoverage": 0.95
}

Call

calculateNormalizedAdLine(records, options)

Returns

object with 9 fields: state, reason_codes, points, ignored_future_revisions, denominator_policy, initial_value, scale, minimum_coverage, …

{
  "state": "resolved",
  "reason_codes": [],
  "points": [
    {
      "session_sequence": 1,
      "session_date": "2026-01-05",
      "effective_at": "2026-01-05T21:00:00Z",
      "available_at": "2026-01-05T21:05:00Z",
      "event_id": "S01",
      "revision": 1,
      "net_advances": 30,
      "mover_count": 90,
      "normalized_breadth": 0.3333333333333333,
      "scaled_contribution": 33.33333333333333,
      "normalized_line": 33.33333333333333,
      "coverage_ratio": 0.98,
      "daily_direction": "advancing",
      "metric": "mover_normalized_advance_decline_line"
    },
    {
      "session_sequence": 2,
      "session_date": "2026-01-06",
      "effective_at": "2026-01-06T21:00:00Z",
      "available_at": "2026-01-06T21:05:00Z",
      "event_id": "S02",
      "revision": 1,
      "net_advances": -20,
      "mover_count": 90,
      "normalized_breadth": -0.2222222222222222,
      "scaled_contribution": -22.22222222222222,
      "normalized_line": 11.111111111111107,
      "coverage_ratio": 0.98,
      "daily_direction": "declining",
      "metric": "mover_normalized_advance_decline_line"
    },
    {
      "session_sequence": 3,
      "session_date": "2026-01-07",
      "effective_at": "2026-01-07T21:00:00Z",
      "available_at": "2026-01-07T21:05:00Z",
      "event_id": "S03",
      "revision": 1,
      "net_advances": 0,
      "mover_count": 80,
      "normalized_breadth": 0,
      "scaled_contribution": 0,
      "normalized_line": 11.111111111111107,
      "coverage_ratio": 0.98,
      "daily_direction": "balanced",
      "metric": "mover_normalized_advance_decline_line"
    }
  ],
  "ignored_future_revisions": 0,
  "denominator_policy": "movers",
  "initial_value": 0,
  "scale": 100,
  "minimum_coverage": 0.95,
  "cutoff": "2026-02-02T00:00:00Z"
}

Diagrams

Normalized Advance/Decline Line — normalized line path
Normalized Advance/Decline Line — scale invariance

Calculation flow

Causal normalized-line publication flow
flowchart LR
  A[Read available time] --> B{Visible at cutoff?}
  B -- No --> C[Count ignored future record]
  B -- Yes --> D[Validate visible event]
  D --> E[Resolve revision heads]
  E --> F{Every expected session resolved?}
  F -- No --> G[Return state and reasons with no points]
  F -- Yes --> H[Verify stable identity seed scale and denominator]
  H --> I[Compute ratio as A minus D over A plus D]
  I --> J[Add scaled ratio to prior line]
  J --> K[Return traceable cumulative points]

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

  • Nasdaq Trader Daily Market Files
  • Nasdaq Trader 2026 daily CSV
  • Nasdaq Trader field definitions
  • McClellan breadth normalization — McClellan Financial Publications
  • StockCharts A/D Percent
  • Evidence map