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

Support/Resistance Clustering

Install and import#

bash
npm install fintech-algorithms
ts
import { clusterPivotLevels } from "fintech-algorithms/geometric-chart-patterns/pivots-and-levels/support-resistance-clustering";

Signature#

clusterPivotLevels(pivots, epsBps, minTouches)

Groups nearby pivots into levels. Clustering in basis points rather than absolute price is what makes the result meaningful across instruments — a $1 band is noise on one stock and a whole level on another.

Parameters#

NameTypeNotes
pivotsPivot[]Pivots from causal detection, carrying kind, indices and price.
epsBpsnumberClustering radius in basis points.
min: 0
minTouchesnumberMinimum pivots required before a cluster counts as a level; below it the group is returned as noise rather than dropped.
min: 1 · integer: true

Returns#

{ clusters, noise }

Accepted levels and the rejected groups — visible, because 'no level here' is itself informative.

Errors#

  • When epsBps is not positive — throws

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

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#

pivots
[
  {
    "kind": "high",
    "event_index": 0,
    "confirmation_index": 1,
    "price": 100
  },
  {
    "kind": "high",
    "event_index": 2,
    "confirmation_index": 3,
    "price": 100.3
  },
  {
    "kind": "high",
    "event_index": 4,
    "confirmation_index": 5,
    "price": 99.9
  }
]

Showing 3 of 4 elements.

epsBps
50
minTouches
3

Call#

clusterPivotLevels(pivots, epsBps, minTouches)

Returns#

object with 2 fields: clusters, noise

{
  "clusters": [
    {
      "kind": "high",
      "cluster_id": "high-0",
      "level": 100,
      "lower": 99.9,
      "upper": 100.3,
      "touch_count": 3,
      "first_confirmation_index": 1,
      "last_confirmation_index": 5,
      "member_event_indexes": [0, 2, 4]
    }
  ],
  "noise": [
    {
      "kind": "high",
      "event_index": 6,
      "confirmation_index": 7,
      "price": 105
    }
  ]
}

Other exports#

This module also exports detectCausalPivots. Every module additionally exports run as an alias of its primary function, and a meta object carrying its catalog id, domain, family, shape and article URL.

Diagrams#

Support/Resistance Clustering — failure atlas
Support/Resistance Clustering — family handoff
Support/Resistance Clustering — knowledge time
Support/Resistance Clustering — parameter boundary

Calculation flow#

Support/Resistance Clustering calculation flow
flowchart LR
    A["Confirmed pivots at knowledge cutoff"] --> B["Reject malformed clocks and prices"]
    B --> C["Split lows from highs"]
    C --> D["Transform price to log price"]
    D --> E["Build inclusive epsilon neighborhoods"]
    E --> F{"At least min touches including self?"}
    F -- "yes" --> G["Core; expand density reachability"]
    F -- "no" --> H["Border if reachable, otherwise noise"]
    G --> I["Median level, member bounds, touch and clock diagnostics"]
    H --> I

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#

  • A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise — Martin Ester, Hans-Peter Kriegel, Jorg Sander, Xiaowei Xu
  • sklearn.cluster.DBSCAN — scikit-learn project
  • Pine Script Concepts: Repainting — TradingView

The rest of the Pivots and Levels family#