Decode market indecision and potential reversals with this comprehensive guide to detecting and strategizing with Harami patterns in TradingView's Pinescript.
The Harami candlestick pattern is a two-candle reversal pattern that signals market indecision and a potential shift in momentum. The word "Harami" means "pregnant" in Japanese, referring to the pattern's appearance where a small second candle is "pregnant" within the larger body of the first candle. Unlike engulfing patterns which show aggression, Harami patterns indicate a slowdown or exhaustion of the previous trend, making them valuable for:
A Harami pattern consists of two candles with distinct characteristics:
A large bearish candle followed by a small bullish candle whose entire body is contained within the body of the first. Often after a downtrend.
A large bullish candle followed by a small bearish candle whose entire body is contained within the body of the first. Often after an uptrend.
Candle 1: Large real body, reflecting the preceding trend.
Candle 2: Small real body, completely contained within the real body of Candle 1.
Opposite Colors (Ideal): Ideally, the colors of the first and second candles are opposite, indicating a struggle.
Context: Most significant when appearing after a clear trend (downtrend for bullish, uptrend for bearish).
//@version=5
indicator("Harami Pattern Detector", overlay=true)
// User input for body size thresholds
largeBodyMinRatio = input.float(0.5, title="Large Body Min Ratio (of ATR)", minval=0.1, maxval=1.0)
smallBodyMaxRatio = input.float(0.3, title="Small Body Max Ratio (of ATR)", minval=0.01, maxval=0.5)
// Helper function to check if a candle's body is large relative to ATR
isLargeBody(idx) =>
math.abs(close[idx] - open[idx]) > ta.atr(14)[idx] * largeBodyMinRatio
// Helper function to check if a candle's body is small relative to ATR
isSmallBody(idx) =>
math.abs(close[idx] - open[idx]) < ta.atr(14)[idx] * smallBodyMaxRatio
// --- Bullish Harami Criteria ---
// 1. Previous candle is a large bearish candle
isC1BearishLarge = close[1] < open[1] and isLargeBody(1)
// 2. Current candle is a small bullish candle
isC2BullishSmall = close > open and isSmallBody(0) // 0 for current bar
// 3. Current candle's body is completely contained within the previous candle's body
// This means current high is below prev open (for bearish C1), and current low is above prev close (for bearish C1)
isC2InsideC1Body = math.max(open, close) < open[1] and math.min(open, close) > close[1]
// Combine for Bullish Harami
isBullishHarami = isC1BearishLarge and isC2BullishSmall and isC2InsideC1Body
// --- Bearish Harami Criteria ---
// 1. Previous candle is a large bullish candle
isC1BullishLarge = close[1] > open[1] and isLargeBody(1)
// 2. Current candle is a small bearish candle
isC2BearishSmall = close < open and isSmallBody(0) // 0 for current bar
// 3. Current candle's body is completely contained within the previous candle's body
// This means current high is below prev close (for bullish C1), and current low is above prev open (for bullish C1)
isC2InsideC1BodyBearish = math.max(open, close) < close[1] and math.min(open, close) > open[1]
// Combine for Bearish Harami
isBearishHarami = isC1BullishLarge and isC2BearishSmall and isC2InsideC1BodyBearish
// Plot signals on the chart
plotshape(isBullishHarami, title="Bullish Harami", location=location.belowbar, color=color.new(color.green, 0), style=shape.triangleup, size=size.small)
plotshape(isBearishHarami, title="Bearish Harami", location=location.abovebar, color=color.new(color.red, 0), style=shape.triangledown, size=size.small)
// Alert conditions (optional)
alertcondition(isBullishHarami, title="Bullish Harami Alert", message="Bullish Harami Pattern Detected!")
alertcondition(isBearishHarami, title="Bearish Harami Alert", message="Bearish Harami Pattern Detected!")
Harami patterns signal indecision, but their true power emerges when confirmed by the market context and other indicators. They act as "warnings" that the trend might be losing steam.
//@version=5
strategy("Harami with Trend Reversal Confirmation", overlay=true)
// Input for Moving Average length
maLength = input(50, "MA Length (for trend)")
ma = ta.ema(close, maLength) // Using EMA for trend detection
// Harami Pattern Detection (simplified from basic example)
largeBodyMinRatio = 0.5
smallBodyMaxRatio = 0.3
isLargeBody(idx) => math.abs(close[idx] - open[idx]) > ta.atr(14)[idx] * largeBodyMinRatio
isSmallBody(idx) => math.abs(close[idx] - open[idx]) < ta.atr(14)[idx] * smallBodyMaxRatio
// Bullish Harami
isC1BearishLarge = close[1] < open[1] and isLargeBody(1)
isC2BullishSmall = close > open and isSmallBody(0)
isC2InsideC1Body = math.max(open, close) < open[1] and math.min(open, close) > close[1]
isBullishHarami = isC1BearishLarge and isC2BullishSmall and isC2InsideC1Body
// Bearish Harami
isC1BullishLarge = close[1] > open[1] and isLargeBody(1)
isC2BearishSmall = close < open and isSmallBody(0)
isC2InsideC1BodyBearish = math.max(open, close) < close[1] and math.min(open, close) > open[1]
isBearishHarami = isC1BullishLarge and isC2BearishSmall and isC2InsideC1BodyBearish
// Trend Context:
// Bullish Harami is more significant after a downtrend (price below MA)
isDowntrend = close < ma and ma < ma[1]
// Bearish Harami is more significant after an uptrend (price above MA)
isUptrend = close > ma and ma > ma[1]
// Strategy Logic with Trend Confirmation
longSignal = isBullishHarami and isDowntrend
shortSignal = isBearishHarami and isUptrend
if (longSignal)
strategy.entry("Long", strategy.long)
if (shortSignal)
strategy.entry("Short", strategy.short)
// Plot MA
plot(ma, "Trend MA", color.blue)
// Plot confirmed signals
plotshape(longSignal, title="Confirmed Bullish Harami", location=location.belowbar, color=color.new(color.navy, 0), style=shape.arrowup, size=size.normal)
plotshape(shortSignal, title="Confirmed Bearish Harami", location=location.abovebar, color=color.new(color.fuchsia, 0), style=shape.arrowdown, size=size.normal)
//@version=5
indicator("Harami with Volume Confirmation", overlay=true)
// Harami Pattern Detection (simplified)
largeBodyMinRatio = 0.5
smallBodyMaxRatio = 0.3
isLargeBody(idx) => math.abs(close[idx] - open[idx]) > ta.atr(14)[idx] * largeBodyMinRatio
isSmallBody(idx) => math.abs(close[idx] - open[idx]) < ta.atr(14)[idx] * smallBodyMaxRatio
isC1BearishLarge = close[1] < open[1] and isLargeBody(1)
isC2BullishSmall = close > open and isSmallBody(0)
isC2InsideC1Body = math.max(open, close) < open[1] and math.min(open, close) > close[1]
isBullishHarami = isC1BearishLarge and isC2BullishSmall and isC2InsideC1Body
isC1BullishLarge = close[1] > open[1] and isLargeBody(1)
isC2BearishSmall = close < open and isSmallBody(0)
isC2InsideC1BodyBearish = math.max(open, close) < close[1] and math.min(open, close) > open[1]
isBearishHarami = isC1BullishLarge and isC2BearishSmall and isC2InsideC1BodyBearish
// Volume Confirmation:
// Volume on the second (smaller) candle should be lower than the first, indicating reduced momentum.
// Or, if it's a "Harami Cross" (second candle is a Doji), volume might be significant.
// For general Harami, reduced volume on the second candle emphasizes indecision.
isVolumeReduced = volume < volume[1] * 0.8 // Current volume is less than 80% of previous
// Combined signals
confirmedBullishHarami = isBullishHarami and isVolumeReduced
confirmedBearishHarami = isBearishHarami and isVolumeReduced
// Plot confirmed signals
barcolor(confirmedBullishHarami ? color.new(color.aqua, 60) : na)
barcolor(confirmedBearishHarami ? color.new(color.purple, 60) : na)
plotshape(confirmedBullishHarami, title="Bullish Harami (Vol Reduced)", location=location.belowbar, color=color.new(color.green, 0), style=shape.labelup, size=size.small, text="BH Vol")
plotshape(confirmedBearishHarami, title="Bearish Harami (Vol Reduced)", location=location.abovebar, color=color.new(color.red, 0), style=shape.labeldown, size=size.small, text="BB Vol")
// Optional: Plot volume for visual check
plot(volume, title="Volume", color=color.gray, style=plot.style_columns)
//@version=5
indicator("Harami with RSI Confirmation", overlay=true)
// RSI Inputs
rsiLength = input(14, "RSI Length")
overbought = input(70, "RSI Overbought Level")
oversold = input(30, "RSI Oversold Level")
// Calculate RSI
rsiValue = ta.rsi(close, rsiLength)
// Harami Pattern Detection (simplified)
largeBodyMinRatio = 0.5
smallBodyMaxRatio = 0.3
isLargeBody(idx) => math.abs(close[idx] - open[idx]) > ta.atr(14)[idx] * largeBodyMinRatio
isSmallBody(idx) => math.abs(close[idx] - open[idx]) < ta.atr(14)[idx] * smallBodyMaxRatio
isC1BearishLarge = close[1] < open[1] and isLargeBody(1)
isC2BullishSmall = close > open and isSmallBody(0)
isC2InsideC1Body = math.max(open, close) < open[1] and math.min(open, close) > close[1]
isBullishHarami = isC1BearishLarge and isC2BullishSmall and isC2InsideC1Body
isC1BullishLarge = close[1] > open[1] and isLargeBody(1)
isC2BearishSmall = close < open and isSmallBody(0)
isC2InsideC1BodyBearish = math.max(open, close) < close[1] and math.min(open, close) > open[1]
isBearishHarami = isC1BullishLarge and isC2BearishSmall and isC2InsideC1BodyBearish
// RSI Confirmation:
// Bullish Harami: RSI in oversold territory or showing bullish divergence
rsiBullishConfirm = rsiValue <= oversold or (rsiValue[1] < oversold and rsiValue > rsiValue[1])
// Bearish Harami: RSI in overbought territory or showing bearish divergence
rsiBearishConfirm = rsiValue >= overbought or (rsiValue[1] > overbought and rsiValue < rsiValue[1])
// Combined signals
signalBullishHarami = isBullishHarami and rsiBullishConfirm
signalBearishHarami = isBearishHarami and rsiBearishConfirm
// Plot signals
plotshape(signalBullishHarami, title="Bullish Harami (RSI Confirmed)", location=location.belowbar, color=color.new(color.lime, 0), style=shape.arrowup, size=size.normal)
plotshape(signalBearishHarami, title="Bearish Harami (RSI Confirmed)", location=location.abovebar, color=color.new(color.orange, 0), style=shape.arrowdown, size=size.normal)
// Plot RSI in a separate pane
plot(rsiValue, "RSI", color.blue, linewidth=2, display=display.pane)
hline(overbought, "Overbought", color.red)
hline(oversold, "Oversold", color.green)
To maximize the effectiveness of Harami patterns in your Pinescript strategies:
The Harami candlestick pattern is a subtle yet powerful signal of market indecision and potential trend exhaustion. By understanding its precise two-candle formation-where the second candle's body is contained within the first's-and its contextual importance after a clear trend, you can leverage it effectively in your trading. Implementing Harami detection in Pinescript allows you to automate signal generation, combine it with complementary indicators like volume and oscillators for higher probability trades, and enhance your price action analysis to make more informed trading decisions on TradingView. Remember, the Harami is a yellow light, signaling caution and the need for confirmation before a potential shift in direction.
Get a high-performance Pinescript analysis tool for actionable market insights, designed for traders on the move.
This strategy runs in live mode on TradingView, helping you identify potential opportunities.
Get Pinescript Strategy