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 ScriptRead 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.
| Bar | High | Low | Open / close |
|---|---|---|---|
| A | 102 | 98 | 100 / 100 |
| B | 104 | 96 | 100 / 100 |
| C | 106 | 94 | 100 / 100 |
| D | 104 | 96 | 100 / 100 |
| E | 102 | 98 | 100 / 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.
// 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)
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 AgentEducational indicator analysis. No measured trading performance is established here. Syntax validation does not prove formula equivalence, execution assumptions or profitability.