Article contents

Evidence and scope

An original indicator offers EQH/EQL, while support/resistance research and repainting documentation provide context. The proposed online clustering algorithm has no demonstrated trading profitability here.

Data and marketsOHLC with valid tick sizes and consistent equity adjustments or futures-roll handling. Prices from different adjustment conventions cannot share a cluster.
Research timeframesMaintain a separate pivot stream for each scale. Fifteen-minute and hourly clusters may overlap in price while retaining different confirmation times.
Three separated highs near 100 form a cluster; a later penetration is evaluated by a separate trigger.Open full-size illustration
Synthetic price and volume. Three highs form a zone 0.25 wide; no actual trading performance is represented. Points are selected event landmarks, not consecutive bars or equal elapsed-time intervals.

Practical workflow

Workflow for Equal highs and equal lows: building pivot clusters without hindsight
The full steps appear below. At each stage, missing data or failed conditions require a recorded rejection reason.
  1. Confirm pivotsKeep occurrence and confirmation timestamps separate.
  2. Check touch separationRequire the same scale and a sufficient excursion between touches.
  3. Check full widthEvaluate the entire cluster, not only its nearest neighbor.
  4. Publish a versionFreeze boundaries and the time they become eligible.
  5. Wait for a triggerTest sweep and breakout strategies independently.

Observable price clustering and the liquidity hypothesis

Two lows at 50 and 50.08 may be approximately equal when normal fluctuations are much larger than their difference. On an instrument with a 0.25 tick, however, 50.08 is not a valid unadjusted trade price. The detector must understand the price grid before applying statistical tolerance.

LuxAlgo exposes EQH/EQL with configurable confirmation [1]. Osler’s research concerns support/resistance within its own empirical scope [2]. Neither establishes a universal win rate for two nearby pivots. The purpose here is an online reference-zone generator for subsequent sweep or breakout research.

Two similar highs are not automatically a double top. A reversal pattern also requires prior context, an intervening valley and a neckline trigger. Equal highs describe location alone; they can occur within an uptrend that later breaks higher. Touch counts do not reveal the volume of stop orders beyond the zone.

Limit the width of the entire cluster

Proposed pivots use three left and three right bars. A high at i is known at i+3 and becomes eligible at i+4. When a cluster is created, freeze A_ref from the preceding ATR14 and eps=max(2 ticks,0.15A_ref). Require at least two same-type, same-scale pivots and a full price spread no larger than 2eps. The zone spans the actual minimum and maximum pivot prices; its center is their median. Do not add eps again to both boundaries.

Proposed touches must be at least five bars apart, with price moving at least eps away between them. This prevents a brief sideways patch from becoming several apparently independent tests. A sample TTL is 100 bars from publication. Age remains a feature to measure rather than a rule that older levels must be stronger.

If a new pivot fits multiple clusters, choose the nearest center, breaking ties in favor of the newer cluster. Reject any addition that makes the entire cluster too wide. Neighbor chaining is insufficient: A can be near B and B near C while A and C are too far apart.

The first qualifying pivot can initialize an unpublished seed. Only a second valid, separated pivot publishes a tradable reference. An implementation must define seed expiry and tie behavior as well as the mature-cluster rule; otherwise isolated pivots can persist indefinitely until a convenient match arrives.

To complete the baseline, an unpublished seed expires 100 bars after its first pivot is confirmed. A published cluster expires 100 bars after first publication; later versions do not extend that deadline. Measure departure only between the two touch occurrence times, excluding bars after the second touch during its confirmation delay. Ignore duplicate pivot IDs and honor eligible_from when publishing.

for p in newly_confirmed_pivots:
  eligible_from = p.confirmed_at+1
  expire_seeds_and_clusters_at_fixed_deadlines(p.confirmed_at)
  candidates = active_clusters_same_type_and_scale(p)
  keep = [c for c in candidates if
          max(c.prices+[p.price])-min(c.prices+[p.price]) <= 2*c.eps]
  c = nearest_center_then_newest(keep)
  if c is None:
    A = ATR14[p.confirmed_at-1]
    if not finite_positive(A): continue
    create_unpublished_seed(p,eps=max(2*tick,0.15*A),
                            seed_expiry=p.confirmed_at+100)
    continue
  if p.id in c.pivot_ids: continue
  if not separated_touch_between_occurrences(p,c,min_bars=5): continue
  append_pivot_once(c,p)
  c.last_touch_index = p.occurred_at
  if c.first_published_at is None:
    c.first_published_at = p.confirmed_at
    c.expiry = p.confirmed_at+100
  publish_new_version(c,eligible_from=eligible_from,expiry=c.expiry)
# Departure is measured only between touch occurrence times.
# Later versions never reset expiry or rewrite active setup snapshots.

Volume around touches must respect confirmation time

A symmetric volume window around a pivot includes future bars relative to the pivot location. Its complete feature is unavailable until the right side finishes. If the zone is published earlier, that feature cannot participate in the decision. A simpler alternative measures from the touch through pivot confirmation using the same duration for each touch.

Declining volume at the second touch can be tested as a weakening-pressure hypothesis. Preserve increasing-volume touches that also fail to cross the level. Neither histogram shape identifies accumulation, distribution or a specific participant. A cluster aligned with the prevailing trend may instead support continuation through the zone.

For intraday data, normalize by the same time slot. Comparing an opening low with a lunchtime low using raw volume confounds touch order with normal session activity. Missing prints or a shorter session must not masquerade as evidence of drying supply.

Synthetic clusters, chaining failure and trade outcomes

With tick=0.01 and A_ref=1, eps=0.15 and maximum width=0.30. Highs at bars 10, 24 and 39 are 100, 100.12 and 100.25. Once all are confirmed and the separation conditions hold, their zone is [100,100.25], centered at 100.12. The final version becomes usable only after the last high is confirmed, not retrospectively at bar 10.

A new high at 100.42 is only 0.17 from 100.25, but it expands the whole group to 0.42. Reject it from the old cluster. Creating a new cluster is a possible policy; moving the coordinates of an already active setup is not. This example exposes why nearest-neighbor chaining can drift without limit.

For a downstream trade example, a later bar reaches 100.50 and closes at 99.80, potentially satisfying an upside-sweep rule with its own buffers. A synthetic short at 99.75, stop at 100.60 and target at 98.05 offers 2R before costs. If the next move reaches 100.80 and protection fills at 100.65, the loss is 0.90. The valid cluster never promised to hold.

A zone becomes a trade only through a separate trigger

Use the same published clusters to test both fading a sweep/reclaim and following an accepted breakout. Shorting merely because a second high has been confirmed is another strategy entirely. Price might not revisit the area for many bars.

Each candidate retains zone_version until expiry. A later qualifying touch creates a new version with its own eligible_at. A running sweep detector must not expand its boundary after a penetration and thereby erase the event. Store source_pivot_ids so every reference can be reconstructed.

After a close-break, a zone can be consumed or moved into a new state under a predetermined policy. Overlap with a prior-day level is useful metadata, not permission to double the risk budget. TradingView’s timing documentation helps distinguish a marker drawn at a past pivot from the time that pivot became known [3].

For simultaneous cluster versions, use an explicit selection rule, such as the oldest eligible version or the nearest outer boundary. Selecting whichever version produces the narrowest profitable stop after the trade would introduce another hidden optimization.

Validate reference quality before trading returns

First require prefix-replay consistency: processing one bar at a time must produce the same published versions as a batch calculation restricted to that prefix. Test equal-price ties, missing bars, corporate actions and changing ticks. Full-sample clustering followed by historical scoring is not an online detector.

Then measure the first later approach to each zone, retaining both breakouts and rejections. Match controls by zone age, width, touch count and regime. Rolling extrema or random grids with similar density are useful comparisons. If the algorithm draws hundreds of levels, nearly every reversal will appear close to one.

Report coverage, candidates per session and the net results of each specific trigger. Keep the same risk allocation when comparing two-touch and three-touch clusters. More touches can mean stronger recognition, repeated consumption of resting liquidity, or simply a longer-lived zone; the data must distinguish these hypotheses rather than assuming a monotonic improvement.

Common pitfalls

One absolute tolerance everywhere

A fixed currency distance can behave differently across volatility regimes; test ATR and tick sensitivity.

Chaining neighboring pivots

Use full maximum-minus-minimum width to prevent drifting zones.

Treating equal highs as a double top

Without reversal context and a neckline, the cluster is only a reference.

Checklist before using this method

Check each item after verifying it on your data. Progress is saved in this browser; it does not certify a profitable strategy.

0/7 items

Frequently asked questions

Must the prices be exactly equal?

No. Define tolerance using the tick and a predetermined volatility reference, then preserve it throughout the test.

Are three touches always stronger than two?

No universal relationship is assumed here. Additional touches may also accompany weakening support or resistance; evaluate them by regime.

Research sources

Each source supports the definition or evidence described beside it. The pseudocode, synthetic examples and proposed parameters require separate validation.

  1. Smart Money ConceptsLuxAlgo on TradingView. Read the original tool description and its evidence limitations. Checked: .
  2. Support for ResistanceFederal Reserve Bank of New York. Read the original research announcement; it does not test this clustering variant. Checked: .
  3. RepaintingTradingView. Read documentation on historical versus real-time calculations. Checked: .

Related methods

Risk note

This content supports education and research design, not financial advice. Backtest is historical simulation, does not guarantee future performance and does not place real trades. Methods in this library are not automatically features available in the app. See methodology and learning center.

Validate rules before risking real capital

Check app support, data and individual simulated trades; advanced detectors may require a separate implementation.

Download Backtest on the App Store