Skip to content

Free TradingView indicator

Candlestick Patterns

Detects engulfing, hammer, shooting star, doji, morning and evening star and inside bars on closed candles, with alerts.

Price actionv1.0TradingView (Pine Script v6) Non-repainting signals Alerts

What it does

The indicator scans every closed candle for classic candlestick patterns and marks them on the chart: bullish and bearish engulfing, hammer (bullish pin bar), shooting star (bearish pin bar), doji, morning star, evening star and inside bar. Each pattern can be switched on or off, and each has its own alert plus combined "any bullish" and "any bearish" alerts.

How it works

Body = |close − open|, range = high − low, and the wicks are measured from the body to the high and low.

  • Bullish engulfing (BE below the candle): a bearish candle followed by a bullish candle whose body is larger and covers the previous body. Bearish engulfing mirrors this.
  • Hammer (H): the lower wick is at least the set multiple of the body and at least half the range, and the upper wick is no more than the set share of the range. Shooting star (SS) is the mirror image.
  • Doji (diamond): the body is no more than the set share of the range, and the candle is not already a hammer or shooting star.
  • Morning star (MS): a strong bearish candle (body at least half its range), then a small candle (body no more than 30% of the first body), then a bullish candle closing above the middle of the first body. Evening star (ES) mirrors this.
  • Inside bar (square): the high is below the previous high and the low above the previous low.

Candles smaller than the ATR filter are ignored. With trend context on, bullish reversal patterns only count when price closes below the EMA, and bearish ones only above it.

How to use it

  • Patterns are most useful at levels that already matter, such as support and resistance, a moving average or a prior swing. The same hammer in the middle of a range means far less.
  • Wait for the next candle to confirm. Many traders only act if price breaks the pattern's high (for bullish patterns) or low (for bearish ones).
  • Higher timeframes give fewer but cleaner patterns. On M1 and M5 the market is noisy and patterns appear constantly.
  • New to the shapes? The candlestick patterns lesson explains each one.

Settings

InputDefaultWhat it changes
Engulfing / pin bars / doji / starsOnPattern families shown
Inside barOffInside-bar markers
Pin bar: wick at least (x body)2.0Strictness of hammers and shooting stars
Pin bar: opposite wick at most (x range)0.25How small the other wick must be
Doji: body at most (x range)0.10Strictness of doji
Ignore candles smaller than (x ATR)0.3Filters tiny candles
Require trend context / EMA lengthOff / 50Trend filter

Limitations

Candlestick patterns are common and many do not lead anywhere, so treat them as context, not as trade signals. Pattern definitions vary between books and platforms, and small threshold changes can add or remove markers. Forex charts from different brokers can show slightly different opens and closes, which changes some patterns. Signals appear only after the candle closes.

Pine Script source

In TradingView open Pine Editor, paste the code, click Save and then Add to chart.

FXP_CandlestickPatterns.pine

90 lines

// © FXPIPS ONLINE — https://fxpips.online/tradingview-indicators/candlestick-patterns/
// License: MIT. Educational tool — not financial advice. Trading involves substantial risk.
//@version=6
// Detects common candlestick patterns on closed candles: bullish / bearish engulfing,
// hammer (bullish pin bar), shooting star (bearish pin bar), doji, morning star,
// evening star and inside bar. Each pattern can be toggled and has its own alert.
indicator("FXP Candlestick Patterns", shorttitle = "FXP Candles", overlay = true)

// ── Inputs ─────────────────────────────────────────────────────────────
grpP       = "Patterns"
useEngulf  = input.bool(true, "Engulfing", group = grpP)
usePin     = input.bool(true, "Hammer / shooting star (pin bars)", group = grpP)
useDoji    = input.bool(true, "Doji", group = grpP)
useStar    = input.bool(true, "Morning / evening star", group = grpP)
useInside  = input.bool(false, "Inside bar", group = grpP)

grpR       = "Rules"
wickMult   = input.float(2.0, "Pin bar: wick at least (x body)", minval = 1.0, step = 0.1, group = grpR)
noseMax    = input.float(0.25, "Pin bar: opposite wick at most (x range)", minval = 0.0, maxval = 0.5, step = 0.05, group = grpR)
dojiMax    = input.float(0.10, "Doji: body at most (x range)", minval = 0.01, maxval = 0.3, step = 0.01, group = grpR)
minRangeAt = input.float(0.3, "Ignore candles smaller than (x ATR)", minval = 0.0, step = 0.1, group = grpR, tooltip = "Filters out tiny, low-information candles. 0 = off.")
atrLen     = input.int(14, "ATR length", minval = 1, group = grpR)

grpF       = "Trend context"
useTrend   = input.bool(false, "Require trend context", group = grpF, tooltip = "Bullish reversal patterns only below the EMA, bearish ones only above it.")
emaLen     = input.int(50, "EMA length", minval = 2, group = grpF)

grpC       = "Colors"
colBull    = input.color(#26a69a, "Bullish", group = grpC)
colBear    = input.color(#ef5350, "Bearish", group = grpC)
colNeutral = input.color(color.gray, "Neutral", group = grpC)

// ── Candle anatomy ─────────────────────────────────────────────────────
float atr    = ta.atr(atrLen)
float ema    = ta.ema(close, emaLen)
float body   = math.abs(close - open)
float rangeC = high - low
float upper  = high - math.max(open, close)
float lower  = math.min(open, close) - low
bool  isBull = close > open
bool  isBear = close < open
bool  bigOk  = rangeC > 0 and rangeC >= minRangeAt * nz(atr)
bool  downCtx = not useTrend or close < ema
bool  upCtx   = not useTrend or close > ema
bool  conf    = barstate.isconfirmed

// ── Patterns ───────────────────────────────────────────────────────────
bool bullEngulf = useEngulf and conf and bigOk and downCtx and isBull and close[1] < open[1] and close >= open[1] and open <= close[1] and body > math.abs(close[1] - open[1])
bool bearEngulf = useEngulf and conf and bigOk and upCtx and isBear and close[1] > open[1] and close <= open[1] and open >= close[1] and body > math.abs(close[1] - open[1])

bool hammer  = usePin and conf and bigOk and downCtx and lower >= wickMult * body and lower >= 0.5 * rangeC and upper <= noseMax * rangeC
bool shooter = usePin and conf and bigOk and upCtx and upper >= wickMult * body and upper >= 0.5 * rangeC and lower <= noseMax * rangeC

bool doji = useDoji and conf and bigOk and body <= dojiMax * rangeC and not hammer and not shooter

float body2   = math.abs(close[2] - open[2])
float range2  = high[2] - low[2]
float mid2    = (open[2] + close[2]) / 2
bool  strong2 = range2 > 0 and body2 >= 0.5 * range2
bool  small1  = math.abs(close[1] - open[1]) <= 0.3 * body2
bool morningStar = useStar and conf and downCtx and strong2 and close[2] < open[2] and small1 and isBull and close > mid2
bool eveningStar = useStar and conf and upCtx and strong2 and close[2] > open[2] and small1 and isBear and close < mid2

bool insideBar = useInside and conf and high < high[1] and low > low[1]

// ── Markers ────────────────────────────────────────────────────────────
plotshape(bullEngulf, "Bullish engulfing", shape.labelup, location.belowbar, colBull, text = "BE", textcolor = color.white, size = size.tiny)
plotshape(bearEngulf, "Bearish engulfing", shape.labeldown, location.abovebar, colBear, text = "BE", textcolor = color.white, size = size.tiny)
plotshape(hammer, "Hammer", shape.labelup, location.belowbar, colBull, text = "H", textcolor = color.white, size = size.tiny)
plotshape(shooter, "Shooting star", shape.labeldown, location.abovebar, colBear, text = "SS", textcolor = color.white, size = size.tiny)
plotshape(doji, "Doji", shape.diamond, location.abovebar, colNeutral, size = size.tiny)
plotshape(morningStar, "Morning star", shape.labelup, location.belowbar, colBull, text = "MS", textcolor = color.white, size = size.tiny)
plotshape(eveningStar, "Evening star", shape.labeldown, location.abovebar, colBear, text = "ES", textcolor = color.white, size = size.tiny)
plotshape(insideBar, "Inside bar", shape.square, location.abovebar, colNeutral, size = size.tiny)

// ── Alerts ─────────────────────────────────────────────────────────────
bool anyBull = bullEngulf or hammer or morningStar
bool anyBear = bearEngulf or shooter or eveningStar

alertcondition(bullEngulf, "Bullish engulfing", "{{ticker}} {{interval}}: bullish engulfing at {{close}}")
alertcondition(bearEngulf, "Bearish engulfing", "{{ticker}} {{interval}}: bearish engulfing at {{close}}")
alertcondition(hammer, "Hammer / bullish pin bar", "{{ticker}} {{interval}}: hammer at {{close}}")
alertcondition(shooter, "Shooting star / bearish pin bar", "{{ticker}} {{interval}}: shooting star at {{close}}")
alertcondition(doji, "Doji", "{{ticker}} {{interval}}: doji at {{close}}")
alertcondition(morningStar, "Morning star", "{{ticker}} {{interval}}: morning star at {{close}}")
alertcondition(eveningStar, "Evening star", "{{ticker}} {{interval}}: evening star at {{close}}")
alertcondition(insideBar, "Inside bar", "{{ticker}} {{interval}}: inside bar")
alertcondition(anyBull, "Any bullish pattern", "{{ticker}} {{interval}}: bullish candlestick pattern at {{close}}")
alertcondition(anyBear, "Any bearish pattern", "{{ticker}} {{interval}}: bearish candlestick pattern at {{close}}")

Key inputs

Key inputs of Candlestick Patterns
InputDefaultDescription
Pattern togglesAll on except inside barTurn each pattern family on or off.
Pin bar: wick at least2.0 × bodyMinimum long-wick length for hammers and shooting stars.
Doji: body at most0.10 × rangeMaximum body size for a doji.
Ignore candles smaller than0.3 × ATRSkips tiny candles (0 = off).
Require trend contextOffBullish patterns only below the EMA, bearish only above.

Educational tools, not advice. Indicators and Expert Advisors describe price; they do not predict it, and past behaviour does not guarantee future results. Test everything on a demo account first and never risk money you cannot afford to lose. See our disclaimer.

Keep exploring

Related tradingview indicators