Causal Pivot Detection
Install and import#
npm install fintech-algorithmsimport { detectCausalPivots } from "fintech-algorithms/geometric-chart-patterns/pivots-and-levels/causal-pivot-detection";Signature#
detectCausalPivots(bars, leftSpan, rightSpan, minSeparation)Finds swing highs and lows using only bars that had already arrived. Most pivot code confirms a pivot with bars that come *after* it and then plots it at the earlier index — which is lookahead bias, and it is invisible on a chart.
Parameters#
| Name | Type | Notes |
|---|---|---|
bars | Bar[] | OHLC bars in chronological order. |
leftSpan | number | Bars before the candidate that must be lower (or higher). min: 1 · integer: true |
rightSpan | number | Bars after the candidate required to confirm it. **This is the confirmation lag**: a pivot at index i is not knowable until i + rightSpan.min: 1 · integer: true |
minSeparation | number | Minimum bars between accepted pivots, which stops a noisy region producing a cluster of them. min: 0 · integer: true |
Returns#
{ kind, event_index, confirmation_index, price }[]
Both indices are returned deliberately: event_index is where the pivot occurred and confirmation_index is when you could have known. Any backtest must use the second.
Errors#
- When leftSpan or rightSpan is less than 1 — throws
Complexity: time O(n × span),
space O(pivots).
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#
[
{
"timestamp": "2026-01-01T00:00:00Z",
"high": 10,
"low": 8,
"close": 9
},
{
"timestamp": "2026-01-01T01:00:00Z",
"high": 12,
"low": 10,
"close": 11
},
{
"timestamp": "2026-01-01T02:00:00Z",
"high": 15,
"low": 13,
"close": 14
}
]Showing 3 of 5 elements.
220Call#
detectCausalPivots(bars, leftSpan, rightSpan, minSeparation)Returns#
object with 1 field: 0
{
"0": {
"kind": "high",
"event_index": 2,
"confirmation_index": 4,
"price": 15,
"separation": 2,
"latency": 2
}
}Diagrams#
Calculation flow#
Causal Pivot Detection calculation flow
flowchart LR
A["Finalized OHLC bar t"] --> B["Candidate i = t - right span"]
B --> C{"Complete left and right windows?"}
C -- "no" --> D["Unavailable"]
C -- "yes" --> E{"Strict-left and inclusive-right extremum?"}
E -- "no" --> F["Reject with reason"]
E -- "yes" --> G{"Separation floor met?"}
G -- "no" --> F
G -- "yes" --> H["Publish event i and confirmation t"]
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#
- Pine Script Techniques: pivots — TradingView
- Pine Script Concepts: Repainting — TradingView
- scipy.signal.find_peaks — SciPy project