Candlestick Pattern Recognition

OnlineTechnicalIndicators.jl includes comprehensive support for candlestick pattern recognition using an incremental (online) approach. All pattern detectors work with streaming data and maintain minimal state.

Overview

Pattern recognition indicators detect specific candlestick formations that often signal potential market reversals or continuations. These patterns are categorized by the number of candles required:

  • Single-candle patterns: Patterns formed by one candlestick (e.g., Doji, Hammer)
  • Two-candle patterns: Patterns formed by two consecutive candlesticks (e.g., Engulfing, Harami)
  • Three-candle patterns: Patterns formed by three consecutive candlesticks (e.g., Morning Star, Three White Soldiers)

Pattern Types and Enumerations

Single Candle Patterns

using OnlineTechnicalIndicators

# Available single-candle patterns
SingleCandlePatternType.NONE
SingleCandlePatternType.DOJI
SingleCandlePatternType.DRAGONFLY_DOJI
SingleCandlePatternType.GRAVESTONE_DOJI
SingleCandlePatternType.HAMMER
SingleCandlePatternType.HANGING_MAN
SingleCandlePatternType.SHOOTING_STAR
SingleCandlePatternType.INVERTED_HAMMER
SingleCandlePatternType.MARUBOZU_BULLISH
SingleCandlePatternType.MARUBOZU_BEARISH
SingleCandlePatternType.SPINNING_TOP

Two Candle Patterns

# Available two-candle patterns
TwoCandlePatternType.NONE
TwoCandlePatternType.BULLISH_ENGULFING
TwoCandlePatternType.BEARISH_ENGULFING
TwoCandlePatternType.BULLISH_HARAMI
TwoCandlePatternType.BEARISH_HARAMI
TwoCandlePatternType.PIERCING_LINE
TwoCandlePatternType.DARK_CLOUD_COVER
TwoCandlePatternType.TWEEZER_TOP
TwoCandlePatternType.TWEEZER_BOTTOM

Three Candle Patterns

# Available three-candle patterns
ThreeCandlePatternType.NONE
ThreeCandlePatternType.MORNING_STAR
ThreeCandlePatternType.EVENING_STAR
ThreeCandlePatternType.THREE_WHITE_SOLDIERS
ThreeCandlePatternType.THREE_BLACK_CROWS
ThreeCandlePatternType.THREE_INSIDE_UP
ThreeCandlePatternType.THREE_INSIDE_DOWN

Pattern Direction

# Pattern direction indicates bullish, bearish, or neutral sentiment
PatternDirection.NEUTRAL
PatternDirection.BULLISH
PatternDirection.BEARISH

Individual Pattern Detectors

Doji

A Doji occurs when open and close prices are virtually equal, indicating market indecision.

doji = Doji{OHLCV{Missing,Float64,Missing}}(body_tolerance = 0.1)
fit!(doji, candle)
result = value(doji)  # Returns SingleCandlePatternVal

Parameters:

  • body_tolerance: Maximum ratio of body to total range (default: 0.1)

Subtypes:

  • Standard Doji: Equal open and close with shadows on both sides
  • Dragonfly Doji: Long lower shadow, no upper shadow (bullish)
  • Gravestone Doji: Long upper shadow, no lower shadow (bearish)

Hammer

A Hammer is characterized by a small body at the top with a long lower shadow.

hammer = Hammer{OHLCV{Missing,Float64,Missing}}(
    body_ratio = 0.33,
    shadow_ratio = 2.0,
    upper_shadow_tolerance = 0.1
)
fit!(hammer, candle)
result = value(hammer)

Parameters:

  • body_ratio: Maximum ratio of body to total range (default: 0.33)
  • shadow_ratio: Minimum ratio of lower shadow to body (default: 2.0)
  • upper_shadow_tolerance: Maximum upper shadow tolerance (default: 0.1)

Shooting Star

A Shooting Star has a small body at the bottom with a long upper shadow.

shooting_star = ShootingStar{OHLCV{Missing,Float64,Missing}}()
fit!(shooting_star, candle)

Marubozu

A Marubozu has little to no shadows, indicating strong directional momentum.

marubozu = Marubozu{OHLCV{Missing,Float64,Missing}}(shadow_tolerance = 0.05)
fit!(marubozu, candle)

Spinning Top

A Spinning Top has a small body with relatively long shadows on both sides.

spinning_top = SpinningTop{OHLCV{Missing,Float64,Missing}}(
    body_ratio = 0.25,
    min_shadow_ratio = 0.3
)
fit!(spinning_top, candle)

Engulfing

An Engulfing pattern occurs when one candle's body completely engulfs the previous candle's body.

engulfing = Engulfing{OHLCV{Missing,Float64,Missing}}(min_body_ratio = 1.1)

# Fit with two consecutive candles
fit!(engulfing, candle1)
fit!(engulfing, candle2)
result = value(engulfing)  # Returns TwoCandlePatternVal

Harami

A Harami occurs when a small candle is contained within the previous candle's body.

harami = Harami{OHLCV{Missing,Float64,Missing}}(max_body_ratio = 0.5)
fit!(harami, candle1)
fit!(harami, candle2)

Piercing Line / Dark Cloud Cover

These patterns involve 50%+ penetration of the previous candle's body.

piercing = PiercingDarkCloud{OHLCV{Missing,Float64,Missing}}(min_penetration = 0.5)
fit!(piercing, candle1)
fit!(piercing, candle2)

Tweezer Top / Bottom

Tweezer patterns have matching highs (top) or lows (bottom).

tweezer = Tweezer{OHLCV{Missing,Float64,Missing}}(tolerance = 0.001)
fit!(tweezer, candle1)
fit!(tweezer, candle2)

Morning Star / Evening Star

Star patterns involve three candles with a small-bodied "star" in the middle.

star = Star{OHLCV{Missing,Float64,Missing}}(
    doji_tolerance = 0.1,
    min_gap_ratio = 0.1
)
fit!(star, candle1)
fit!(star, candle2)
fit!(star, candle3)
result = value(star)  # Returns ThreeCandlePatternVal

Three White Soldiers / Three Black Crows

These patterns involve three consecutive candles in the same direction with progressive closes.

soldiers = ThreeSoldiersCrows{OHLCV{Missing,Float64,Missing}}(min_progress = 0.2)
fit!(soldiers, candle1)
fit!(soldiers, candle2)
fit!(soldiers, candle3)

Three Inside Up / Down

Combination of Harami followed by confirmation candle.

three_inside = ThreeInside{OHLCV{Missing,Float64,Missing}}(max_harami_ratio = 0.5)
fit!(three_inside, candle1)
fit!(three_inside, candle2)
fit!(three_inside, candle3)

Comprehensive Pattern Detector

The CandlestickPatternDetector aggregates all pattern detectors and can detect multiple patterns simultaneously.

detector = CandlestickPatternDetector{OHLCV{Missing,Float64,Missing}}(
    enable_single = true,
    enable_two = true,
    enable_three = true
)

# Stream candles
fit!(detector, candle1)
fit!(detector, candle2)
fit!(detector, candle3)

result = value(detector)  # Returns AllPatternsVal

# Access detected patterns
for pattern in result.single_patterns
    println("Single: $(pattern.pattern), confidence: $(pattern.confidence)")
end

for pattern in result.two_patterns
    println("Two: $(pattern.pattern), confidence: $(pattern.confidence)")
end

for pattern in result.three_patterns
    println("Three: $(pattern.pattern), confidence: $(pattern.confidence)")
end

Parameters:

  • enable_single: Enable single-candle detection (default: true)
  • enable_two: Enable two-candle detection (default: true)
  • enable_three: Enable three-candle detection (default: true)

Return Values

SingleCandlePatternVal

struct SingleCandlePatternVal{T}
    pattern::SingleCandlePattern
    confidence::T          # 0.0 to 1.0
    direction::Direction   # BULLISH, BEARISH, or NEUTRAL
end

TwoCandlePatternVal

struct TwoCandlePatternVal{T}
    pattern::TwoCandlePattern
    confidence::T
    direction::Direction
end

ThreeCandlePatternVal

struct ThreeCandlePatternVal{T}
    pattern::ThreeCandlePattern
    confidence::T
    direction::Direction
end

AllPatternsVal

struct AllPatternsVal{S}
    single_patterns::Vector{SingleCandlePatternVal{S}}
    two_patterns::Vector{TwoCandlePatternVal{S}}
    three_patterns::Vector{ThreeCandlePatternVal{S}}
end

Incremental Pattern Detection

All pattern detectors use an incremental (online) approach:

  1. Minimal State: Each detector maintains only the necessary lookback window (1, 2, or 3 candles)
  2. Real-time Updates: Patterns are detected as new candles arrive
  3. Confidence Scoring: Each detected pattern includes a confidence score (0.0 to 1.0)
  4. Memory Efficient: Uses circular buffers to store historical candles

Example: Streaming Pattern Detection

detector = Doji{OHLCV{Missing,Float64,Missing}}()

for candle in live_candle_stream
    fit!(detector, candle)

    result = value(detector)
    if !ismissing(result) && result.pattern != SingleCandlePatternType.NONE
        println("Pattern detected: $(result.pattern)")
        println("Confidence: $(result.confidence)")
        println("Direction: $(result.direction)")
    end
end

Tips and Best Practices

  1. Use with Context: Patterns are more reliable when considered with market context (trend, volume, support/resistance)

  2. Confidence Scores: Higher confidence scores indicate better pattern fit. Consider using thresholds:

    if result.confidence > 0.7
        # High-confidence pattern
    end
  3. Combine Patterns: Use CandlestickPatternDetector to detect multiple patterns and look for confirmations

  4. Performance: Individual detectors are faster. Use them if you only need specific patterns

  5. Trend Context: Some patterns (Hammer vs Hanging Man) require trend context for proper interpretation

Complete Example

using OnlineTechnicalIndicators

# Create detector for all patterns
detector = CandlestickPatternDetector{OHLCV{Missing,Float64,Missing}}()

# Simulate streaming data
candles = [
    OHLCV(100.0, 105.0, 98.0, 103.0),
    OHLCV(103.0, 104.0, 102.0, 103.0),  # Doji
    OHLCV(100.0, 110.0, 100.0, 110.0),  # Marubozu
]

for (i, candle) in enumerate(candles)
    fit!(detector, candle)

    result = value(detector)
    println("After candle $i:")

    # Check single-candle patterns
    for pattern in result.single_patterns
        if pattern.confidence > 0.5
            println("  $(pattern.pattern): $(pattern.direction), confidence: $(pattern.confidence)")
        end
    end

    # Check two-candle patterns
    for pattern in result.two_patterns
        if pattern.confidence > 0.5
            println("  $(pattern.pattern): $(pattern.direction), confidence: $(pattern.confidence)")
        end
    end

    # Check three-candle patterns
    for pattern in result.three_patterns
        if pattern.confidence > 0.5
            println("  $(pattern.pattern): $(pattern.direction), confidence: $(pattern.confidence)")
        end
    end
end

API Reference

OnlineTechnicalIndicators.SingleCandlePatternValType
SingleCandlePatternVal{T}

Return value type for single candlestick pattern indicators.

Fields

  • pattern::SingleCandlePatternType.SingleCandlePattern: The detected pattern
  • confidence::T: Confidence level (0.0 to 1.0)
  • direction::PatternDirection.Direction: Pattern direction (BULLISH, BEARISH, NEUTRAL)
source
OnlineTechnicalIndicators.TwoCandlePatternValType
TwoCandlePatternVal{T}

Return value type for two-candle pattern indicators.

Fields

  • pattern::TwoCandlePatternType.TwoCandlePattern: The detected pattern
  • confidence::T: Confidence level (0.0 to 1.0)
  • direction::PatternDirection.Direction: Pattern direction (BULLISH, BEARISH, NEUTRAL)
source
OnlineTechnicalIndicators.ThreeCandlePatternValType
ThreeCandlePatternVal{T}

Return value type for three-candle pattern indicators.

Fields

  • pattern::ThreeCandlePatternType.ThreeCandlePattern: The detected pattern
  • confidence::T: Confidence level (0.0 to 1.0)
  • direction::PatternDirection.Direction: Pattern direction (BULLISH, BEARISH, NEUTRAL)
source
OnlineTechnicalIndicators.AllPatternsValType
AllPatternsVal{S}

Return value type containing all detected candlestick patterns.

Fields

  • single_patterns::Vector{SingleCandlePatternVal{S}}: All detected single-candle patterns
  • two_patterns::Vector{TwoCandlePatternVal{S}}: All detected two-candle patterns
  • three_patterns::Vector{ThreeCandlePatternVal{S}}: All detected three-candle patterns
source
OnlineTechnicalIndicators.DojiType
Doji{Tohlcv}(; body_tolerance = DOJI_BODY_TOLERANCE, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The Doji type implements a Doji candlestick pattern detector.

A Doji is characterized by having an open and close that are virtually equal, indicating indecision in the market.

Parameters

  • body_tolerance: Maximum ratio of body size to full range to be considered a Doji (default: 0.1)

Output

source
OnlineTechnicalIndicators.HammerType
Hammer{Tohlcv}(; body_ratio = HAMMER_BODY_RATIO, shadow_ratio = HAMMER_SHADOW_RATIO, upper_shadow_tolerance = HAMMER_UPPER_SHADOW_TOLERANCE, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The Hammer type implements Hammer and Hanging Man candlestick pattern detectors.

A Hammer is a bullish reversal pattern with a small body at the top and a long lower shadow. A Hanging Man is the same pattern but appears at the end of an uptrend (bearish).

Parameters

  • body_ratio: Maximum ratio of body to total range (default: 0.33)
  • shadow_ratio: Minimum ratio of lower shadow to body (default: 2.0)
  • upper_shadow_tolerance: Maximum ratio of upper shadow to total range (default: 0.1)

Output

source
OnlineTechnicalIndicators.ShootingStarType
ShootingStar{Tohlcv}(; body_ratio = SHOOTING_STAR_BODY_RATIO, shadow_ratio = SHOOTING_STAR_SHADOW_RATIO, lower_shadow_tolerance = SHOOTING_STAR_LOWER_SHADOW_TOLERANCE, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The ShootingStar type implements Shooting Star and Inverted Hammer candlestick pattern detectors.

A Shooting Star is a bearish reversal pattern with a small body at the bottom and a long upper shadow. An Inverted Hammer is the same pattern but appears at the end of a downtrend (bullish).

Parameters

  • body_ratio: Maximum ratio of body to total range (default: 0.33)
  • shadow_ratio: Minimum ratio of upper shadow to body (default: 2.0)
  • lower_shadow_tolerance: Maximum ratio of lower shadow to total range (default: 0.1)

Output

source
OnlineTechnicalIndicators.MarubozuType
Marubozu{Tohlcv}(; shadow_tolerance = MARUBOZU_SHADOW_TOLERANCE, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The Marubozu type implements Marubozu candlestick pattern detector.

A Marubozu is characterized by having little to no shadows (wicks), indicating strong directional momentum. A bullish Marubozu closes at/near the high, a bearish one closes at/near the low.

Parameters

  • shadow_tolerance: Maximum ratio of shadow to total range (default: 0.05)

Output

source
OnlineTechnicalIndicators.SpinningTopType
SpinningTop{Tohlcv}(; body_ratio = SPINNING_TOP_BODY_RATIO, min_shadow_ratio = SPINNING_TOP_MIN_SHADOW_RATIO, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The SpinningTop type implements Spinning Top candlestick pattern detector.

A Spinning Top has a small body with relatively long shadows on both sides, indicating indecision with buying and selling pressure roughly equal.

Parameters

  • body_ratio: Maximum ratio of body to total range (default: 0.25)
  • min_shadow_ratio: Minimum ratio of each shadow to total range (default: 0.3)

Output

source
OnlineTechnicalIndicators.EngulfingType
Engulfing{Tohlcv}(; min_body_ratio = ENGULFING_MIN_BODY_RATIO, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The Engulfing type implements Bullish and Bearish Engulfing candlestick pattern detector.

An Engulfing pattern occurs when a candle's body completely engulfs the previous candle's body.

  • Bullish Engulfing: Down candle followed by up candle that engulfs it
  • Bearish Engulfing: Up candle followed by down candle that engulfs it

Parameters

  • min_body_ratio: Minimum ratio of current body to previous body (default: 1.1)

Output

source
OnlineTechnicalIndicators.HaramiType
Harami{Tohlcv}(; max_body_ratio = HARAMI_MAX_BODY_RATIO, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The Harami type implements Bullish and Bearish Harami candlestick pattern detector.

A Harami pattern occurs when a small candle's body is contained within the previous candle's body.

  • Bullish Harami: Down candle followed by small up candle contained within it
  • Bearish Harami: Up candle followed by small down candle contained within it

Parameters

  • max_body_ratio: Maximum ratio of current body to previous body (default: 0.5)

Output

source
OnlineTechnicalIndicators.PiercingDarkCloudType
PiercingDarkCloud{Tohlcv}(; min_penetration = PIERCING_MIN_PENETRATION, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The PiercingDarkCloud type implements Piercing Line and Dark Cloud Cover candlestick pattern detectors.

  • Piercing Line: Bullish reversal where a down candle is followed by an up candle that closes above the midpoint of the first candle's body
  • Dark Cloud Cover: Bearish reversal where an up candle is followed by a down candle that closes below the midpoint of the first candle's body

Parameters

  • min_penetration: Minimum penetration ratio into previous candle's body (default: 0.5 = 50%)

Output

source
OnlineTechnicalIndicators.TweezerType
Tweezer{Tohlcv}(; tolerance = TWEEZER_TOLERANCE, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The Tweezer type implements Tweezer Top and Tweezer Bottom candlestick pattern detectors.

  • Tweezer Top: Two consecutive candles with matching highs, indicating resistance
  • Tweezer Bottom: Two consecutive candles with matching lows, indicating support

Parameters

  • tolerance: Maximum relative difference between prices to be considered matching (default: 0.001 = 0.1%)

Output

source
OnlineTechnicalIndicators.StarType
Star{Tohlcv}(; doji_tolerance = STAR_DOJI_TOLERANCE, min_gap_ratio = STAR_MIN_GAP_RATIO, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The Star type implements Morning Star and Evening Star candlestick pattern detectors.

  • Morning Star: Bullish reversal with down candle, small-bodied star, then up candle
  • Evening Star: Bearish reversal with up candle, small-bodied star, then down candle

Parameters

  • doji_tolerance: Maximum body ratio for middle candle to be considered a star (default: 0.1)
  • min_gap_ratio: Minimum gap between star and adjacent candles (default: 0.1)

Output

source
OnlineTechnicalIndicators.ThreeSoldiersCrowsType
ThreeSoldiersCrows{Tohlcv}(; min_progress = THREE_SOLDIERS_MIN_PROGRESS, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The ThreeSoldiersCrows type implements Three White Soldiers and Three Black Crows candlestick pattern detectors.

  • Three White Soldiers: Three consecutive bullish candles with progressive closes
  • Three Black Crows: Three consecutive bearish candles with progressive closes

Parameters

  • min_progress: Minimum ratio of progression between consecutive candles (default: 0.2)

Output

source
OnlineTechnicalIndicators.ThreeInsideType
ThreeInside{Tohlcv}(; max_harami_ratio = THREE_INSIDE_MAX_HARAMI_RATIO, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The ThreeInside type implements Three Inside Up and Three Inside Down candlestick pattern detectors.

  • Three Inside Up: Bullish pattern - Harami followed by bullish confirmation
  • Three Inside Down: Bearish pattern - Harami followed by bearish confirmation

Parameters

  • max_harami_ratio: Maximum ratio of second candle body to first candle body for Harami (default: 0.5)

Output

source
OnlineTechnicalIndicators.CandlestickPatternDetectorType
CandlestickPatternDetector{Tohlcv}(; enable_single = true, enable_two = true, enable_three = true, input_filter = always_true, input_modifier = identity, input_modifier_return_type = Tohlcv)

The CandlestickPatternDetector type implements a comprehensive candlestick pattern detector that aggregates all available pattern detection algorithms.

Parameters

  • enable_single: Enable single-candle pattern detection (default: true)
  • enable_two: Enable two-candle pattern detection (default: true)
  • enable_three: Enable three-candle pattern detection (default: true)

Output

source

See Also

  • OHLCV Data Structure (see Usage documentation)
  • Technical Indicators (see Indicators Support documentation)
  • Pattern Recognition Examples (see examples directory in repository)