Why Harami Patterns Matter in Pine Script
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:
- Identifying potential trend reversals, especially after a prolonged move.
- Signaling market indecision and a pause in current momentum.
- Providing an early warning of a possible trend change.
Understanding Bullish and Bearish Harami Patterns
A Harami pattern consists of two candles with distinct characteristics:
- First Candle (Large Body): A large candle (bullish or bearish, depending on the preceding trend) indicating strong directional movement.
- Second Candle (Small Body/Inside Bar): A small-bodied candle (can be bullish or bearish) that opens and closes *completely within the real body* of the first candle. The second candle is often referred to as an "inside bar."
The color of the second candle is generally opposite to the first, but the key is that its body is contained within the first. The overall pattern suggests that the strong directional move of the first candle was followed by a period of consolidation or indecision, indicating a loss of momentum.
Bullish Harami Pattern
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.
Bearish Harami Pattern
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).
Basic Harami Pattern Detection in Pine Script
Here's how to create a basic indicator to detect both Bullish and Bearish Harami patterns in Pine Script v5:
//@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!")
Advanced Harami Strategies
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.
1. Harami with Trend Confirmation (Using Moving Average)
//@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 // Corrected typo from `isBearamiHarami`
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)
2. Harami with Volume Confirmation
//@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)
3. Harami with RSI Confirmation
//@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)
Optimizing Harami Pattern Performance
To maximize the effectiveness of Harami patterns in your Pine Script strategies:
- Context is Crucial: A Harami pattern gains significance when it appears after a prolonged trend (downtrend for bullish, uptrend for bearish). It signifies a loss of momentum in the existing trend.
- Confirmation is Key: Harami patterns are more about indecision than strong reversals. Always wait for a confirming candle (e.g., a strong bullish candle after a bullish Harami) before acting on the signal.
- Volume Analysis: A decrease in volume on the second, smaller Harami candle can strengthen the signal of indecision or exhaustion, especially after a high-volume trend.
- Support & Resistance: When a Harami forms at a significant support or resistance level, its reliability as a potential reversal signal increases.
- Harami Cross: A particularly strong variation is the "Harami Cross," where the second candle is a Doji. This indicates extreme indecision and a higher probability of reversal.
- Timeframe: While visible on all timeframes, signals on higher timeframes (e.g., daily, weekly) generally carry more weight and are considered more reliable for sustained reversals.
Common Harami Pattern Pitfalls to Avoid
- Ignoring Body Containment: The absolute most critical rule is that the *entire body* of the second candle must be within the *entire body* of the first candle. Wicks can extend outside, but the body must be contained.
- Lack of Prior Trend: A Harami in a choppy or ranging market has little to no predictive power. It needs a clear preceding trend to signal potential reversal.
- Small First Candle: If the first candle is not substantially larger than the second, the "pregnant" analogy doesn't hold, and the pattern loses significance.
- Trading in Isolation: Relying solely on the Harami pattern without confirmation from subsequent price action, volume, or other indicators can lead to false signals or premature entries.
- Confusing with Engulfing: While both are two-candle patterns, an engulfing pattern shows aggression, while a Harami shows indecision. Do not confuse them.
Conclusion
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 Pine Script 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.