Support/Resistance Clustering
Install and import#
npm install fintech-algorithmsimport { 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#
| Name | Type | Notes |
|---|---|---|
pivots | Pivot[] | Pivots from causal detection, carrying kind, indices and price. |
epsBps | number | Clustering radius in basis points. min: 0 |
minTouches | number | Minimum 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#
[
{
"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.
503Call#
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#
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.
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