TradingView pattern analysis

Pattern recognition indicators: check the rule and the confirmation time

A pattern recognition indicator labels price bars that match its programmed definition. Different scripts can disagree about the same chart because their body ratios, trend filters, pivot tolerances and confirmation times differ. A label records a detected condition; it does not establish a win rate, identify institutional orders or prove that a reversal will follow.

Explore the Coding Agent

Start with the built-in pattern tools

In TradingView Supercharts, open Indicators, metrics, and strategies, then Technicals → Patterns. Add the specific indicator and read its tooltip and settings. The separate Screener has a Candlestick Pattern field for filtering symbols by supported patterns. Its Strong, Medium and Weak categories are internal classifications, not a published probability of profit. A chart script does not automatically run across a watchlist.

  • For repeatable comparison, use the same feed, session, interval and standard candle type. Synthetic chart prices can change which shapes qualify.
  • Record the selected trend mode. TradingView’s bullish engulfing indicator offers SMA-based trend detection or no trend detection; a different EMA rule is not an exact clone.

Specify the geometry instead of relying on a pattern name

A hammer, engulfing candle and double top require different definitions. There is no single wick-ratio rule that covers all three. The following are questions to resolve in a specification, not universal trading rules.

Pattern familyWhat the detector must defineTiming or interpretation limit
One-candle shapeBody and upper/lower shadow ratios; doji handling; trend context.OHLC values can change until the candle closes. A long lower shadow alone does not prove a reversal.
Two-candle body engulfingOpposite body directions; body coverage; equality and gap rules.Covering the prior body does not require covering its entire high-low range. Volume is an additional filter.
Pivot-based chart formationLeft/right confirmation bars, price tolerance, spacing and breakout rule.A pivot requiring three bars on its right becomes knowable three bars later, even if its label is drawn back on the pivot.
Multi-symbol screeningSupported universe, intervals, data availability and the exact expression.A chart layout or screenshot review is not evidence that the same detector scans every symbol.

An inspectable body-engulfing variant

The example below checks only the active chart. Bullish requires a bearish prior body, a bullish current body that covers it, and a strictly larger current body. It also requires the close above an EMA and volume above a prior-volume average. Bearish uses the opposite body and EMA comparisons. This is an educational continuation-filter variant; it is not TradingView’s built-in reversal detector, a hammer detector or a geometric pattern engine.

  • Equality at either body boundary is allowed, but equal body sizes fail. Prior or current doji bodies fail the direction checks. Wicks are not used.
  • Both labels and alert conditions require a closed chart bar. The EMA line still updates during an open bar.
  • The volume baseline excludes the current bar. Missing current volume or an unavailable/nonpositive baseline suppresses events. Pine’s moving average can skip missing observations; this is not a guarantee of complete volume history.
  • The script waits at least max(EMA length, volume length) prior chart bars. Results still depend on the loaded history, feed and inputs. It does not diagnose every missing or corrected bar.
Closed-bar body-engulfing events with an EMA and prior-volume filterpinescript
//@version=6
indicator("Closed-bar body engulfing example [Pineify]", overlay=true)
int trendLength = input.int(50, "Trend EMA length", minval=1, maxval=500)
int volumeLength = input.int(20, "Prior volume average length", minval=1, maxval=500)
float trendEMA = ta.ema(close, trendLength)
float priorVolumeAverage = ta.sma(volume[1], volumeLength)
float body = math.abs(close - open)
float previousBody = math.abs(close[1] - open[1])
bool ready = bar_index >= math.max(trendLength, volumeLength) and not na(priorVolumeAverage) and priorVolumeAverage > 0 and not na(volume) and not na(trendEMA)
bool volumeAboveAverage = ready and volume > priorVolumeAverage
bool bullishBody = close[1] < open[1] and close > open and open <= close[1] and close >= open[1] and body > previousBody
bool bearishBody = close[1] > open[1] and close < open and open >= close[1] and close <= open[1] and body > previousBody
bool bullishEvent = barstate.isconfirmed and volumeAboveAverage and bullishBody and close > trendEMA
bool bearishEvent = barstate.isconfirmed and volumeAboveAverage and bearishBody and close < trendEMA
plot(trendEMA, title="Trend EMA", color=color.blue)
plotshape(bullishEvent, title="Bullish body engulfing", style=shape.labelup, location=location.belowbar, color=color.green, text="BULL", textcolor=color.white, size=size.tiny)
plotshape(bearishEvent, title="Bearish body engulfing", style=shape.labeldown, location=location.abovebar, color=color.red, text="BEAR", textcolor=color.white, size=size.tiny)
alertcondition(bullishEvent, title="Bullish body engulfing", message="Closed-bar bullish body engulfing: {{ticker}} {{interval}}, close {{close}}. Research event, not an order.")
alertcondition(bearishEvent, title="Bearish body engulfing", message="Closed-bar bearish body engulfing: {{ticker}} {{interval}}, close {{close}}. Research event, not an order.")

Check examples that should and should not trigger

These numbers are hypothetical condition checks after warm-up. For the first three rows, assume the previous candle opens at 100 and closes at 98, the EMA is 100, and the prior-volume average is 1,000. Prices share the chart’s quote units; volume uses the selected feed’s units.

Current inputsExpected resultReason
Open 97, close 101, volume 1,200; bar closedBullish eventBody 4 exceeds prior body 2, covers it, and passes both filters.
Open 98, close 100, volume 1,200; bar closedNo bullish eventEqual body size is rejected; the close also does not exceed the EMA.
Open 97, close 101, volume 1,000; bar closedNo bullish eventVolume must be strictly greater than the baseline.
First-row values while the bar remains openNo confirmed eventThe closed-bar gate applies to both labels and alerts.
First-row prices with unavailable current volumeNo eventThe script does not treat missing volume as confirmation.
Prior open 98/close 100; current open 101/close 97; EMA 98, volume 1,200, average 1,000; closedBearish eventThe mirrored body and below-EMA comparisons pass.

Set up alerts and record when information became available

Add the script to the intended chart, open Create Alert, and select its Bullish body engulfing or Bearish body engulfing condition. Choose Once Per Bar Close. The code exposes conditions; it does not create a running alert by itself. TradingView alerts run on realtime bars and use a saved script/input snapshot. Recreate an alert after changing the source or settings if it should use the new configuration.

  • Bar-close alert frequency controls notifications. It does not, by itself, stop an independently plotted marker from appearing intrabar. This example gates the marker expression as well.
  • For a pivot-based script, log the confirmation timestamp separately from the plotted pivot timestamp. Compare live observations with a later reload before describing its behavior.
  • Closed-bar logic does not protect against every source of historical changes, including feed corrections, changed inputs or different loaded history. The example uses no higher-timeframe request or backward plotting.

Evaluate a filter without inventing accuracy

Define an outcome before counting successful patterns: for example, the return after a fixed number of bars, or which of a specified stop and target is reached first. These are different experiments. Specify entry timing, order assumptions, costs, ambiguous same-bar outcomes and a separate evaluation period. Compare the unfiltered and filtered versions on the same eligible sample.

  • Report event counts and rejected cases alongside the outcome distribution. A filter can reduce sample size without improving results.
  • Above-average volume measures activity relative to the chosen baseline; it does not identify the traders responsible.
  • No win rate or measured performance is provided for this example. Syntax validation is separate from chart-behavior checks and strategy testing.
Where Pineify fits

Pine Script AI Coding Agent

Describe your pattern boundaries, confirmation timing and missing-data rules to draft a custom Pine indicator. Inspect the generated source and test it against positive and negative examples.

Explore the Coding Agent

Frequently asked questions

Educational rule specification, not investment advice. Hypothetical cases and syntax validation do not establish trading performance. No live orders or historical strategy test are included.

Sources and verification