{talib} includes 61 candlestick pattern recognition functions ported from TA-Lib. This vignette covers how they work, what they return, and how to tune their sensitivity.
A candlestick shows four prices for a chosen time period: Open, High, Low, and Close (OHLC).
The real body is the segment between the Open and the Close. If the Close is above the Open the candle is bullish; otherwise it is bearish.
The upper shadow extends from the top of the real body to the High; the lower shadow extends from the bottom of the real body to the Low. Together the shadows show how far price moved beyond the Open-Close range.
Candlestick patterns are defined by comparing the size and position of bodies and shadows—within a single candle or across a sequence of consecutive candles.
The 61 pattern functions can be loosely grouped by how many candles they inspect:
| Candles | Examples |
|---|---|
| Single-candle | doji(), hammer(),
shooting_star(), marubozu(),
spinning_top(), long_line(),
short_line() |
| Two-candle | engulfing(), harami(),
harami_cross(), piercing(),
dark_cloud_cover(), kicking() |
| Three-candle | morning_star(),
evening_star(), three_inside(),
three_outside(), three_white_soldiers(),
three_black_crows() |
| Four+ candle | concealing_baby_swallow(),
rising_falling_three_methods(), mat_hold(),
break_away() |
Every function has a descriptive snake_case name and an uppercase
alias matching the TA-Lib convention (doji /
CDLDOJI, engulfing /
CDLENGULFING, etc.).
All pattern functions require OHLC columns
(~open + high + low + close) and return an integer matrix
of the same length as the input:
1 — bullish pattern (or
direction-neutral pattern) identified-1 — bearish pattern identified0 — no patternSome patterns are inherently directional (e.g.,
engulfing() returns both 1 and
-1), while others are direction-neutral (e.g.,
doji() always returns 1 for identified
patterns).
By default, patterns are normalized to
1/-1/0. The original TA-Lib
encoding (100/-100/0) can be
restored with:
eps parameterSeven patterns accept an eps (penetration) parameter
that controls how far one candle must intrude into the body of another.
These are morning_star(), evening_star(),
morning_doji_star(), evening_doji_star(),
abandoned_baby(), dark_cloud_cover(), and
mat_hold(). The default is eps = 0 for all of
them.
NA valuesEvery pattern has a lookback period: the number of
initial rows that are returned as NA because the algorithm
needs historical context before it can evaluate. The lookback depends on
two things: the number of candles in the pattern itself, and the
N parameter that controls how many prior candles are used
to compute reference values for body/shadow classification.
Pattern recognition in {talib} relies on classifying each candle’s body and shadows as “long”, “short”, “doji-like”, etc. These classifications are controlled by two parameters per setting:
N (lookback): How many prior candles
to average when computing the reference value.alpha (sensitivity): A multiplier
applied to the reference value. The current candle is tested against
alpha * reference.All settings are modified via options() and take effect
on the next pattern function call.
The complete list of settings, their defaults, and what they control:
Body settings:
| Setting | Option prefix | N | alpha | Rule |
|---|---|---|---|---|
| BodyLong | talib.BodyLong |
10 | 1.0 | Body is long when longer than the average of the N previous bodies |
| BodyVeryLong | talib.BodyVeryLong |
10 | 3.0 | Body is very long when longer than 3x the average |
| BodyShort | talib.BodyShort |
10 | 1.0 | Body is short when shorter than the average |
| BodyDoji | talib.BodyDoji |
10 | 0.1 | Body is doji-like when shorter than 10% of the average high-low range |
Shadow settings:
| Setting | Option prefix | N | alpha | Rule |
|---|---|---|---|---|
| ShadowLong | talib.ShadowLong |
0 | 1.0 | Shadow is long when longer than the real body |
| ShadowVeryLong | talib.ShadowVeryLong |
0 | 2.0 | Shadow is very long when longer than 2x the real body |
| ShadowShort | talib.ShadowShort |
10 | 1.0 | Shadow is short when shorter than half the average shadow sum |
| ShadowVeryShort | talib.ShadowVeryShort |
10 | 0.1 | Shadow is very short when shorter than 10% of the average high-low range |
Distance settings:
| Setting | Option prefix | N | alpha | Rule |
|---|---|---|---|---|
| Near | talib.Near |
5 | 0.2 | Distance is “near” when <= 20% of the average high-low range |
| Far | talib.Far |
5 | 0.6 | Distance is “far” when >= 60% of the average high-low range |
| Equal | talib.Equal |
5 | 0.05 | Distance is “equal” when <= 5% of the average high-low range |
N)Changing N alters how many prior candles form the
reference average. A shorter lookback makes the reference more reactive
to recent price action:
alpha)Changing alpha makes the classification more or less
permissive. A higher alpha means a wider acceptance
threshold:
## more permissive: accept bodies up to 20% of the high-low range
options(talib.BodyDoji.alpha = 0.2)
sum(abs(talib::doji(talib::BTC)), na.rm = TRUE)
#> [1] 109The default alpha = 0.1 for BodyDoji means: “the real
body is doji-like when it’s shorter than 10% of the average high-low
range over the past 10 candles.” Doubling it to 0.2 loosens
the criterion and identifies more patterns.
Different patterns depend on different settings. As a general rule:
doji(),
doji_star(), dragonfly_doji(),
gravestone_doji(), long_legged_doji(),
rickshaw_man()) are primarily controlled by
BodyDoji.engulfing(),
harami(), dark_cloud_cover(),
piercing()) depend on BodyLong and
BodyShort.morning_star(),
evening_star(), abandoned_baby()) depend on
BodyShort, BodyLong, and the shadow
settings.hammer(),
shooting_star(), inverted_hammer(),
hanging_man()) primarily depend on ShadowLong
and BodyShort.kicking(),
matching_low(), counter_attack()) use the
Near, Far, and Equal
settings.Candlestick patterns integrate with the {talib} charting system. Bullish patterns are marked below the candle, bearish patterns above, and direction-neutral patterns use a neutral style:
Multiple patterns can be layered on the same chart. Each call to
indicator() adds its markers to the existing price
chart.
The underlying library, TA-Lib, is a long-standing and well-known library but this R wrapper is still in its early stage. All contributions, suggestions, and bug reports are welcome.