TradingView indicator guides

TD Supply & Demand Points: Pattern Rules and Confirmation Delay

This Pineify example detects specific high and low patterns. Level 1 compares three bars; Level 2 requires five bars with strictly ordered sides. Markers are drawn back on the candidate peak or trough, although the condition becomes knowable one or two bars later. These patterns do not measure traded supply, demand or the probability that a level will hold.

Inspect the Pine Script

Read the inequalities in chronological order

For three consecutive bars A, B and C, Level 1 supply requires high B greater than both high A and high C. Demand requires low B less than both low A and low C. Equal highs or lows fail the corresponding strict condition. The candidate is B; C is the bar on which the result is calculated.

For five bars A through E, Level 2 supply requires highs A < B < C and C > D > E. Demand requires lows A > B > C and C < D < E. The candidate is C and the result is calculated on E. There are two rises into the peak and two declines away from it, not three rising steps.

Level 2 is stricter than merely requiring the center to exceed all four neighbors. Highs 101, 100, 105, 102, 103 have a unique center maximum, but fail this implementation because the left side does not rise toward the center and the right side does not keep falling. A generic two-left/two-right pivot detector can therefore produce different results.

The TD name is retained from the example. This high/low geometry is not a Setup or Countdown implementation, and this page does not establish equivalence to an authorized DeMARK indicator. DeMARK’s Sequential overview describes a different multi-stage method using close comparisons and additional qualifications.

A reproducible five-bar example

The following prices are synthetic and use open = close = 100 on every bar. They demonstrate the boolean rules, not a trading result.

Both a supply and demand pattern can occur at the same center
BarHighLowOpen / close
A10298100 / 100
B10496100 / 100
C10694100 / 100
D10496100 / 100
E10298100 / 100

At D, Level 1 sees C as both a local high and a local low. At E, Level 2’s high and low inequalities both pass for C. Two crosses can therefore mark the same candle. Every close remains 100: the patterns do not prove that closing prices reversed, that sellers controlled the high, or that buyers defended the low.

Changing E’s high from 102 to 104 breaks Level 2 supply because D and E now have equal highs. Demand still passes because the lows are unchanged. Changing E’s high to 105 also fails Level 2 even though C remains the highest of the five bars. These checks distinguish the actual monotonic-side rule from a general swing-high rule.

Separate the marker bar from the decision bar

Level 1 uses offset −1 and Level 2 uses offset −2. For a candidate at bar 100, Level 1 is calculated at bar 101 and Level 2 at bar 102. A closed-bar interpretation becomes available at the close of those confirmation bars. The marker is not delayed an additional one or two bars after the whole pattern completes.

The copied code has no barstate.isconfirmed gate. On a live confirmation bar, its high can rise enough or low fall enough to invalidate a pattern that appeared earlier in that bar. For example, Level 1 supply with previous highs 102 and 106 initially qualifies if current high is 104, then fails if current high reaches 106. A fixed negative plotting offset does not prevent that change.

TradingView distinguishes live-bar changes from plotting into the past. Both matter here. Once the confirmation bar closes, unchanged historical OHLC fixes these finite comparisons; data revisions or different chart aggregation can still change the inputs. Do not infer an executable entry on the candidate bar from a marker drawn there later.

For an auditable adaptation, optionally show a separate confirmation-bar marker and store the candidate price together with the time it became known. A strategy must use the confirmation time for decisions and define subsequent order timing. It must not backdate entry to the visually marked high or low.

What the copied source includes

The function returns four booleans, but the fixed argument is 1. Only the two Level 1 outputs can be true in this copied example. Editing the call to 2 selects Level 2; it does not enable both levels together. There is no Inputs-panel selector because the source has no input declaration. Pineify’s separate Visual Editor configuration exposes a Pattern Level field.

Values other than 1 or 2 make all four returned outputs false. Two intermediate selection variables in the helper are unused, so their fallback branch does not make unsupported levels operate as Level 2. Supply and demand are independent conditions and may both be true.

Red and green crosses use plotshape above and below bars; their screen positions are not numeric order prices. The script does not draw persistent zones, track retests, invalidate old levels, request other timeframes, inspect volume, create alerts or place orders. The max_labels_count setting does not impose a 500-marker limit on plotshape output, which is distinct from label objects.

Turn a pattern into a testable level rule

If researching retests, define the reference price, zone width, first eligible retest after confirmation, expiration, invalidation and what counts as a successful reaction. Record unretested patterns separately. Without those definitions, a hold rate is not reproducible; this page establishes no measured reliability for either level or market.

Level 2’s center also satisfies Level 1 geometry one bar earlier when the corresponding sequence is observed, but this does not imply a fixed frequency ratio or improved trading outcomes. More conditions reduce the eligible pattern set while increasing confirmation delay. They may exclude useful and unhelpful cases alike.

A rolling highest/lowest value includes current data and retains an extreme until it leaves the window. It does not have a universal N/2-bar detection delay. Parabolic SAR is a different stateful trailing calculation, not a fixed historical pivot. Compare exact outputs and timing before combining methods.

Higher and lower timeframe patterns share underlying price data and are not statistically independent confirmations by default. A multi-timeframe adaptation needs explicit completed-data handling. For all variants, define fills, gaps, position sizing and costs separately; a recognized pattern does not supply those rules.

Pine Script v6: implementation and limits

The complete source retains the original high/low comparisons and backward plot offsets. It deliberately documents the current implementation rather than silently changing confirmation behavior. No observed performance is supplied by these booleans.

Pine Script v6
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify

//@version=6
indicator(title="TD Supply & Demand Points", overlay=true, max_labels_count=500)

p_ta_td_supply_demand_points(simple int patternLevel) =>
    // Level 1: 3-candle pattern
    isSupplyPoint_L1 = high[1] > high[2] and high[1] > high
    isDemandPoint_L1 = low[1] < low[2] and low[1] < low

    // Level 2: 5-candle pattern
    isSupplyPoint_L2 = high[2] > high[3] and high[3] > high[4] and high[2] > high[1] and high[1] > high
    isDemandPoint_L2 = low[2] < low[3] and low[3] < low[4] and low[2] < low[1] and low[1] < low

    isSupplyPoint = patternLevel == 1 ? isSupplyPoint_L1 : isSupplyPoint_L2
    isDemandPoint = patternLevel == 1 ? isDemandPoint_L1 : isDemandPoint_L2

    supplyPointL1 = isSupplyPoint_L1 and patternLevel == 1
    demandPointL1 = isDemandPoint_L1 and patternLevel == 1
    supplyPointL2 = isSupplyPoint_L2 and patternLevel == 2
    demandPointL2 = isDemandPoint_L2 and patternLevel == 2

    [supplyPointL1, demandPointL1, supplyPointL2, demandPointL2]

// Call with default pattern level
[p_ind_1_supplyPointL1, p_ind_1_demandPointL1, p_ind_1_supplyPointL2, p_ind_1_demandPointL2] = p_ta_td_supply_demand_points(1)

// Plot supply and demand points
plotshape(p_ind_1_supplyPointL1, title="Supply Point L1", location=location.abovebar, color=color.rgb(255, 0, 0, 0), style=shape.xcross, size=size.tiny, offset=-1)
plotshape(p_ind_1_demandPointL1, title="Demand Point L1", location=location.belowbar, color=color.rgb(0, 255, 0, 0), style=shape.xcross, size=size.tiny, offset=-1)
plotshape(p_ind_1_supplyPointL2, title="Supply Point L2", location=location.abovebar, color=color.rgb(255, 0, 0, 0), style=shape.xcross, size=size.tiny, offset=-2)
plotshape(p_ind_1_demandPointL2, title="Demand Point L2", location=location.belowbar, color=color.rgb(0, 255, 0, 0), style=shape.xcross, size=size.tiny, offset=-2)
Existing indicator chart preview
Existing visual preview. Verify exact values against the source; the image is not a performance result.

Specify a checkable adaptation in Pineify

Ask the Pine Script AI Coding Agent for an explicit level selector, optional closed-bar confirmation and a second marker on the actual detection bar. If adding persistent zones or a strategy, define their eligibility and timing first. Review generated source and verify the synthetic cases before using market data.

Open Pine Script AI Coding Agent

Educational indicator analysis. No measured trading performance is established here. Syntax validation does not prove formula equivalence, execution assumptions or profitability.

Implementation questions

It is calculated two bars after the candidate center. A closed-bar interpretation waits for that second later bar to close. The negative offset only draws the marker back on the center.

No. It requires strictly ascending then descending highs, or strictly descending then ascending lows. A center extreme with unordered side bars can fail.

Yes. A candle can be both the local highest high and local lowest low. The two conditions do not inspect closing direction or volume.

No. The live confirmation bar can invalidate a provisional pattern, and markers are drawn into the past. Closed historical comparisons are stable only while their data remains unchanged.

No. The fixed call selects Level 1 and there are no input controls. Level 2 requires changing the call or adding an explicit selector; other values return no enabled signals.