Candlesticks
All functions · nseries package
Candle anatomy
RealBody, UpperShadow, LowerShadow and CandleAverage take the close c as the receiver and the open o, high h and low l as arguments: the columns of one bar table, so each must have the receiver’s length (otherwise the result is Series{}), and they are not right-aligned. The methods follow TA-Lib 0.6.4’s candle macros and default candle settings (ta_utility.h and ta_global.c, the same in substance from TA-Lib 0.4.0 to its main branch): RealBody is TA_REALBODY, |c - o|; UpperShadow and LowerShadow are TA_UPPERSHADOW and TA_LOWERSHADOW, written with Go’s built-in max and min; and CandleAverage is TA_CANDLEAVERAGE, factor times the mean of a measure over the n bars before each bar, evaluated as factor * (S/n) / d, where S is the window’s sum and d is 2 for the sum of the shadows and 1 otherwise. Maximum and Minimum, under “Math”, give the body’s top and bottom, c.Maximum(o) and c.Minimum(o). The columns can be any bar table of equal lengths, the views of the “Heikin-Ashi” category included: with haO and haC from HeikinAshiOpen and HeikinAshiClose, haC.RealBody(haO) is haC.Sub(haO).Abs(), the size of Valcu’s haDiffCO, bit for bit, and the kit’s colour haC.GTE(haO) counts a tie as white where Valcu’s white body, haC.GT(haO), does not.
TA-Lib’s patterns keep a running total of each measure, adding the new bar and subtracting the oldest. CandleAverage uses Average’s rolling sum instead: for n >= 1 it equals R.Average(n).Shift(1).Mul(factor).Div(d).SetN(n, math.NaN()) bit for bit, with R the measure. TA-Lib’s thresholds and these agree to rounding where no partial sum overflows, and bit for bit where the window sums are exact, as on prices in quarters (the primer of TA-Lib’s regression tests, which fixes every threshold its test file prints, uses whole numbers; some of its scenario bars use tenths). The rolling sum is window-local: a NaN or infinite measure affects only the windows that hold it, while TA-Lib’s running total stays NaN for the rest of the call.
TA-Lib’s candle settings
A TA-Lib candlestick pattern compares a candle’s parts with thresholds, its candle settings. The threshold of a setting (kind, n, factor) is c.CandleAverage(o, h, l, kind, n, factor). TA-Lib’s eleven defaults, with TA-Lib’s own comments, are:
| Setting | kind | n | factor | TA-Lib’s comment |
|---|---|---|---|---|
| BodyLong | CandleRealBody | 10 | 1 | longer than the average of the 10 previous candles’ real body |
| BodyVeryLong | CandleRealBody | 10 | 3 | longer than 3 times the average of the 10 previous candles’ real body |
| BodyShort | CandleRealBody | 10 | 1 | shorter than the average of the 10 previous candles’ real bodies |
| BodyDoji | CandleHighLow | 10 | 0.1 | shorter than 10% the average of the 10 previous candles’ high-low range |
| ShadowLong | CandleRealBody | 0 | 1 | longer than the real body |
| ShadowVeryLong | CandleRealBody | 0 | 2 | longer than 2 times the real body |
| ShadowShort | CandleShadows | 10 | 1 | shorter than half the average of the 10 previous candles’ sum of shadows |
| ShadowVeryShort | CandleHighLow | 10 | 0.1 | shorter than 10% the average of the 10 previous candles’ high-low range |
| Near | CandleHighLow | 5 | 0.2 | <= 20% of the average of the 5 previous candles’ high-low range |
| Far | CandleHighLow | 5 | 0.6 | >= 60% of the average of the 5 previous candles’ high-low range |
| Equal | CandleHighLow | 5 | 0.05 | <= 5% of the average of the 5 previous candles’ high-low range |
The comparison is not part of a setting: each pattern writes its own. TA-Lib’s doji is a real body no larger than BodyDoji, inclusive, c.RealBody(o).LTE(c.CandleAverage(o, h, l, CandleHighLow, 10, 0.1)): 1 on a doji and 0 elsewhere, including the ten warm-up bars. On the primer of TA-Lib’s regression tests, twelve bars with bodies of 2 and ranges of 10, the thresholds at the next bar are those its test file prints: 2 for BodyLong and BodyShort, 1 for BodyDoji and ShadowVeryShort, 0.5 for Equal and 2 for Near.
TA-Lib’s core patterns
Thirteen methods are TA-Lib 0.6.4’s core candlestick functions with its default candle settings. Each takes the close c as the receiver and the open o, high h and low l as arguments, c.CandleHammer(o, h, l), compares the parts of one to four candles with the thresholds of the settings above, each c.CandleAverage(o, h, l, kind, n, factor) bit for bit, and returns TA-Lib’s integer output divided by 100 at every bar: 1 or -1 on a pattern, 0.8 or -0.8 on the one-end ties of the engulfing pattern and the harami, and +0 on every other bar, NaN on none. CandleDoji’s 1 means that a doji is present, not that it is bullish. The dark cloud cover and the two stars take a penetration, as TA-Lib’s functions do: a fraction of the first candle’s real body, which the caller passes (TA-Lib’s defaults are 0.5 and 0.3).
| Method | TA-Lib | Values | Lookback | Penetration |
|---|---|---|---|---|
| CandleDoji | CDLDOJI | 1 | 10 | none |
| CandleEngulfing | CDLENGULFING | 1, -1, 0.8, -0.8 | 2 | none |
| CandleHammer | CDLHAMMER | 1 | 11 | none |
| CandleHangingMan | CDLHANGINGMAN | -1 | 11 | none |
| CandleInvertedHammer | CDLINVERTEDHAMMER | 1 | 11 | none |
| CandleShootingStar | CDLSHOOTINGSTAR | -1 | 11 | none |
| CandleHarami | CDLHARAMI | 1, -1, 0.8, -0.8 | 11 | none |
| CandlePiercing | CDLPIERCING | 1 | 11 | fixed at 0.5 |
| CandleDarkCloudCover | CDLDARKCLOUDCOVER | -1 | 11 | 0.5 |
| CandleMorningStar | CDLMORNINGSTAR | 1 | 12 | 0.3 |
| CandleEveningStar | CDLEVENINGSTAR | -1 | 12 | 0.3 |
| CandleThreeWhiteSoldiers | CDL3WHITESOLDIERS | 1 | 12 | none |
| CandleThreeBlackCrows | CDL3BLACKCROWS | -1 | 13 | none |
The lookback is TA-Lib’s at its default settings: bars 0 to L-1 are 0 whatever the data, so the first bar that can fire is TA-Lib’s, and a table of L bars or fewer is all 0. For the engulfing pattern, the hammer, the hanging man, the inverted hammer, the shooting star and the crows, every value the decision reads already exists at bar L-1, and that bar is 0 even where TA-Lib’s condition holds. A penetration that is NaN, +Inf, -Inf or negative gives zeros of the receiver’s length; every other value is valid, 0 and values above 1 included, and the lengths are checked first: the open, high and low must each have the receiver’s length, otherwise the result is Series{}.
Bar t of each pattern reads these prices and thresholds, a threshold at bar k being the setting’s value at index k, whose window is the ten bars before k (five for Near and Far; ShadowLong is the body of bar k itself):
- CandleDoji: o and c at bar t, and BodyDoji at bar t;
- CandleEngulfing: o and c at bars t-1 and t, and no threshold;
- CandleHammer and CandleHangingMan: o, h, l and c at bar t, l at bar t-1 (the hammer) or h at bar t-1 (the hanging man), BodyShort, ShadowLong and ShadowVeryShort at bar t, and Near at bar t-1;
- CandleInvertedHammer and CandleShootingStar: o, h, l and c at bar t, o and c at bar t-1, and BodyShort, ShadowLong and ShadowVeryShort at bar t;
- CandleHarami: o and c at bars t-1 and t, BodyLong at bar t-1 and BodyShort at bar t;
- CandlePiercing: o, l and c at bar t-1, o and c at bar t, and BodyLong at bars t-1 and t;
- CandleDarkCloudCover: o, h and c at bar t-1, o and c at bar t, and BodyLong at bar t-1;
- CandleMorningStar and CandleEveningStar: o and c at bars t-2 to t, BodyLong at bar t-2, and BodyShort at bars t-1 and t;
- CandleThreeWhiteSoldiers: o, h and c at bars t-2 to t, ShadowVeryShort at bars t-2 to t, Near and Far at bars t-2 and t-1, and BodyShort at bar t;
- CandleThreeBlackCrows: o, h and c at bar t-3, o, l and c at bars t-2 to t, and ShadowVeryShort at bars t-2 to t.
So the engulfing pattern, the harami and the two stars read only the open and the close, since their thresholds are body settings. The thresholds agree with TA-Lib’s running totals to rounding, and exactly where the window sums are exact, as on prices in quarters, so a decision can differ from TA-Lib’s only where a compared value sits on a threshold that the two sums round differently. After ten bars with opens, lows and closes of 0 and ranges summing to 87.5, a body of 0.875 is a doji here, where the rolling sum gives BodyDoji 0.875 exactly, and not in TA-Lib, whose running total gives 0.8749999999999999.
- Missing values. A bar whose decision reads a NaN, +Inf or -Inf, among the prices listed or in the window of a listed threshold, is 0, whatever the pattern’s other conditions give, and every other bar keeps its value: on flat bars, a NaN high at bar 19 makes CandleDoji 0 on bars 20 to 29, whose BodyDoji windows hold it, and 1 again from bar 30. TA-Lib differs twice. It compares infinities as numbers, so an infinite close is a white candle that engulfs anything and an infinite range makes a threshold of +Inf that every body is below, a doji. And its running totals, once they hold a NaN, keep it to the end of the call (an infinite price makes the total infinite, and a NaN when it leaves the window; a total that overflowed on finite measures stays infinite), so that every later bar of a pattern that reads the setting is 0. A window of huge finite measures can overflow to +Inf too; that threshold is then not finite, and the bar is 0.
- The white tie. A candle with c = o counts as white, as in TA-Lib. The second of three white soldiers may be a doji, the crows’ white candle may be one, and a doji first candle can be engulfed by a black candle and not by a white one. Otherwise the engulfing pattern is its own mirror on reflected prices (o, h, l and c negated, the high and the low swapped), the harami is its own mirror, and the morning and evening stars are each other’s, bit for bit, since every candle whose colour the stars test has a body above a threshold. The other pairs are not exact mirrors.
- One-end ties. When the two real bodies match at one end, CandleEngulfing and CandleHarami give 0.8 or -0.8, TA-Lib’s 80. TA-Lib before 0.6.0, the 0.4 line that many wrappers shipped, has no such tie and gives 0 on those bars. Bodies equal at both ends give 0 in the engulfing pattern.
- TA-Lib 0.8.1. The penetration lines are written
c + B*pandc - B*p, with B the first body and the product rounded before the addition or subtraction, as in TA-Lib 0.6.4. TA-Lib 0.8.1 writes the morning star’s line as a fused multiply-add,fma(B, p, c), which can move it by one ulp: on TA-Lib’s morning-star scenario at penetration 0.296, a third close of 103.552 lies above the 0.6.4 line, 103.55199999999999, and gives 1 here and in 0.6.4, while the fused line is 103.552 itself and gives 0. It writes the piercing pattern’s midpoint asfma(B, 0.5, c), but the product by 0.5 is exact unless the body is subnormal, so the two agree on practical data.
No pattern tests the trend; the recipes below add context, and the sign and the full patterns are compositions. For a result x:
sign := x.GT(0).Sub(x.LT(0))
full := x.Abs().EQ(1)
masked := x.MaskNonFinite(o, h, l, c)The sign folds the ties into 1 and -1, and full marks the full patterns only. masked is NaN where a price of the pattern’s own bar is not finite, and only there: a bar that is 0 because an earlier bar or a threshold’s window holds the missing value keeps its 0.
Nison’s hammer has a lower shadow at least twice the body (strict here, as TA-Lib’s comparisons are; see “The hammer’s shadow”), and Sung’s closes below its 20-day average:
nison := c.CandleHammer(o, h, l).Mul(c.LowerShadow(o, l).GT(c.RealBody(o).Mul(2)))
sung := c.CandleHammer(o, h, l).Mul(c.LT(c.Average(20)))nison is bit for bit TA-Lib’s hammer with ShadowVeryLong in place of ShadowLong, since a lower shadow above twice a body that is not negative is above the body. sung is 0 on bars 0 to 18, where Average passes the closes through, and his hanging man closes above the average. Hellal and Meyers’s ten-bar trend rule (under “Evidence”) is applied the same way, as a series of 0 and 1 that multiplies the result; their engulfing pattern also asks a bullish engulfing bar’s high to exceed the prior high and a bearish one’s low to undercut the prior low, which TA-Lib does not test.
Ties and missing values
- Colour. A candle is white when
c.GTE(o)is 1 and black when it is 0. A tie, c = o, counts as white, as in TA-Lib’sTA_CANDLECOLOR; Nison calls such a candle a doji, with no colour. A NaN close or open reads as black, since a comparison with NaN gives 0:c.GTE(o).MaskNonFinite(c, o)keeps it missing. - Body ends.
UpperShadow,LowerShadow,MaximumandMinimumuse the built-inmaxandmin, which give NaN when either price is NaN, and +0 (max) or -0 (min) from the two signed zeros. TA-Lib’s macros choose the body’s end withc >= o, which is false when either price is NaN: its upper shadow then reads the open, so it is finite when only the close is NaN, and its lower shadow reads the close, so it is finite when only the open is NaN. On a close of -0 with an open of +0 they take the close as the top and the open as the bottom. On other prices the two agree. - Warm-up.
CandleAverageis NaN on its first n bars, and on every bar when n is at least the length, not the package’s +0: a +0 threshold would pass every<=test, while a comparison with NaN gives 0. - A setting read k bars back.
Shift(k)pads +0 at the start, so mask the warm-up again:c.CandleAverage(o, h, l, kind, n, factor).Shift(k).SetN(n+k, math.NaN()). When n can be nearmath.MaxInt, n+k overflows andSetNthen masks nothing;SetN(min(n, len(c))+k, math.NaN())masks the same bars.
Evidence
The evidence for candlestick patterns is weak. Marshall, Young and Rose (2006) found no value in them on the stocks of the Dow Jones Industrial Average (1992-2002). Hellal and Meyers tested the engulfing pattern with a ten-bar trend rule on 14 currency pairs and 21 ETFs and stocks (2000-2011): over 1,740 patterns, the best holding period gave +0.052% per trade before costs, indistinguishable from zero. Sung found no bullish edge after hammers: prices generally headed down after the umbrella candles he studied, and more so after hammers.
No TA-Lib pattern tests the trend, although Nison defines the hammer and the engulfing pattern by the trend they end; the sources’ trend filters are recipes. Sung’s hammer closes below its 20-day average, c.LT(c.Average(20)) (0 on bars 0 to 18, where Average passes the closes through), and his hanging man above it; Hellal and Meyers compare the highest high of the pattern’s three bars (the lowest low, for the bearish case) with the highest high and the lowest low of the previous ten bars.
Recipes
The parts of a candle that have no method of their own are compositions:
- the range,
h.Sub(l). Upper shadow plus lower shadow plus real body, added in that order, equals it exactly on well-formed bars with 0 < l and h <= 2l, and on prices in quarters, and to rounding otherwise; - the colour,
c.GTE(o), above; - the signed body,
c.Sub(o), whose n-bar average equalsc.QStick(o, c, n)to rounding; - the body’s top and bottom,
c.Maximum(o)andc.Minimum(o). The arithmetic form of the top,o.Add(c).Add(o.Sub(c).Abs()).Div(2), is not exact.
Gaps
TA-Lib’s four gap macros compare a bar with the bar before it, strictly. Shift pads +0, so without the mask bar 0 would gap up on positive prices:
bodyGapUp := c.Minimum(o).GT(c.Maximum(o).Shift(1)).SetN(1, 0)
bodyGapDown := c.Maximum(o).LT(c.Minimum(o).Shift(1)).SetN(1, 0)
gapUp := l.GT(h.Shift(1)).SetN(1, 0)
gapDown := h.LT(l.Shift(1)).SetN(1, 0)The first two are the real-body gaps; the last two are the candle gaps, Nison’s rising and falling windows. A comparison with NaN gives 0, so a missing price reads as no gap.
The hammer’s shadow
Nison’s hammer has a lower shadow “at least two to three times the height of the real body”; TA-Lib’s hammer asks for a lower shadow longer than the body, its ShadowLong setting. The strict two-times test is the ShadowVeryLong setting, which equals c.RealBody(o).Mul(2) bit for bit (Nison’s “at least” would be GTE; TA-Lib’s comparisons are strict):
twice := c.LowerShadow(o, l).GT(c.RealBody(o).Mul(2))
taLib := c.LowerShadow(o, l).GT(c.CandleAverage(o, h, l, CandleRealBody, 0, 1))Cline’s candle signature
Cline cuts each bar into k = 5 segments of the larger of its range and the mean range of the ten bars before it, and rounds each part half away from zero (Excel’s ROUND, which Round matches), so a bar is coded by three digits from 0 to 5 on a well-formed bar, its signature HO:HC:OL:
avg := c.CandleAverage(o, h, l, CandleHighLow, 10, 1)
D := h.Sub(l).Maximum(avg)
ho := h.Sub(o).Mul(5).Div(D).Round()
hc := h.Sub(c).Mul(5).Div(D).Round()
ol := o.Sub(l).Mul(5).Div(D).Round()
code := ho.Mul(36).Add(hc.Mul(6)).Add(ol)The first valid bar is 10: before it the average is NaN, and so is every part. code packs the signature into one number in base k + 1 = 6. On Cline’s twelve monthly SPY bars of 2013, the recipe reproduces all twelve printed signatures from his printed averages, and from its own averages those of November and December, 3:0:1 and 2:0:2. A flat bar after ten flat bars has D = 0, where Div gives 0, so its signature is 0:0:0.
Ruggiero’s graded long body
Ruggiero grades a body between 0, at zeroCof times the average body, and 1, at oneCof times it, linearly in between; his tests use 15 bars, oneCof = 2 and zeroCof = 1:
body := c.RealBody(o)
avg := body.Average(15)
z, one := avg.Mul(zeroCof), avg.Mul(oneCof)
scale := one.Sub(z)
long := body.Sub(z).Div(scale).Clamp(0, 1).SetN(14, math.NaN())
long = long.If(func(_ float64, i int) bool { return scale[i] == 0 }, math.NaN(), long)His average includes the current bar, as TradeStation’s does, unlike TA-Lib’s settings; bars 0 to 13, where Average passes the bodies through, are masked. The numerator is body - z, as his text and figure describe; the printed code subtracts the one level, which would give 0 below it. Where the scale is 0, his code substitutes 99.99 and Div gives 0, which would read as “not long”, so the recipe masks those bars to NaN. With oneCof below zeroCof (0.3 and 1, his small body) the same lines grade a small body; his small-body code is not printed. His clause that relaxes the test after a long bar is left out: as printed it relaxes nothing clearly.
CandleAverage
func (s Series) CandleAverage(o, h, l Series, kind CandleRange, n int, factor float64) Series
CandleAverage returns TA-Lib’s candle-setting threshold: factor times the mean of the chosen measure over the n bars before each bar, the bar’s own measure when n is 0, halved for the shadows, and NaN on the first n bars.
The receiver c is the close. CandleRealBody measures |c[t] - o[t]|, CandleHighLow measures h[t] - l[t], and CandleShadows measures (h[t] - max(o[t], c[t])) + (min(o[t], c[t]) - l[t]), using the built-in max and min. The divisor d is 2 for CandleShadows and 1 for the other kinds. Prices are unchecked, so shadows and ranges may be negative. Only the columns needed by the chosen measure affect its values.
For n >= 1, bar t uses the n bars t-n to t-1, excluding the current bar. With S the sum over that window, the TA_CANDLEAVERAGE order is factor * (S/n) / d: first form the mean, then multiply by factor, then divide by d. The mean is the value Average computes for the same measure at bar t-1. The result is R.Average(n).Shift(1).Mul(factor).Div(d).SetN(n, math.NaN()) bit for bit, where R is the chosen measure. For n = 0, the result is R.Mul(factor).Div(d) bit for bit, evaluated as (factor * R[t]) / d on every bar.
TA-Lib uses a running total: on finite data without overflow it agrees to rounding, and bit for bit when sums are exact. A NaN in that running total persists. Here missing data is window-local: a NaN or infinity affects only windows containing that measure, and later windows recover. A window containing NaN or both signs of infinity gives NaN; otherwise an infinity keeps its sign before scaling. A zero factor times an infinity gives NaN. Partial sums of finite measures can overflow, giving +Inf, -Inf or NaN according to the summation grouping, even when the exact window sum is finite. Multiplication by factor can also overflow before division by d. A slice that starts later gives the same values from its bar n on only to rounding, and bit for bit when the window sums are exact, because the grouping of the rolling sum depends on where it started; where a partial sum overflows, one start can give a finite value and another an infinity.
Bars before n are NaN, including every bar when n equals or exceeds the length. This departs from the package’s +0 warm-up: a +0 threshold can pass a <= test before an average is available, whereas comparisons with NaN return 0. To read a setting k bars back, use Shift(k), then SetN(n+k, math.NaN()) to mask the +0 padding as well as the original warm-up. When n can be near math.MaxInt, n+k overflows and SetN then masks nothing; SetN(min(n, len(c))+k, math.NaN()) masks the same bars without overflow.
TA-Lib 0.6.4’s eleven default candle settings, as (kind, n, factor), are BodyLong (CandleRealBody, 10, 1), BodyVeryLong (CandleRealBody, 10, 3), BodyShort (CandleRealBody, 10, 1), BodyDoji (CandleHighLow, 10, 0.1), ShadowLong (CandleRealBody, 0, 1), ShadowVeryLong (CandleRealBody, 0, 2), ShadowShort (CandleShadows, 10, 1), ShadowVeryShort (CandleHighLow, 10, 0.1), Near (CandleHighLow, 5, 0.2), Far (CandleHighLow, 5, 0.6) and Equal (CandleHighLow, 5, 0.05). Each pattern supplies its own comparison operator. For instance, c.RealBody(o).LTE(c.CandleAverage(o, h, l, CandleHighLow, 10, 0.1)) is TA-Lib’s inclusive doji rule, giving 1 on a doji and 0 elsewhere, including the warm-up bars. The thirteen TA-Lib core patterns of the Candlesticks category read every threshold they compare with from this method at these defaults, bit for bit.
The open o, high h and low l must each have the receiver’s length, whichever kind is chosen, otherwise the result is Series{}. These columns form one bar table and are not right-aligned. Lengths are checked before parameters. A negative n, an unknown kind, or a NaN or infinite factor returns fresh +0 values of the receiver’s length. Every finite factor is accepted, including 0, -0, negative factors and subnormals. Every non-negative n is valid. Empty or nil inputs of equal length give an empty, non-nil result for any parameters. The method takes O(len(s)) time, returns fresh storage and does not modify its inputs.
CandleDarkCloudCover
func (s Series) CandleDarkCloudCover(o, h, l Series, penetration float64) Series
CandleDarkCloudCover is -1 on TA-Lib’s dark cloud cover (CDLDARKCLOUDCOVER), a black candle that opens above the high of a long white candle and closes inside its body, more than penetration times the body below its close, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleDarkCloudCover(o, h, l, 0.5). Bar t is -1 when bar t-1 is white, c >= o, with a real body |c - o| above BodyLong at bar t-1, bar t is black, c < o, o[t] > h[t-1], c[t] > o[t-1] and c[t] < c[t-1] - penetration times the first body, the product rounded before the subtraction as in TA-Lib 0.6.4; otherwise it is 0. Every test is strict, and there is no size test on bar t. The setting BodyLong (CandleRealBody, 10, 1) is the mean body of bars t-11 to t-2.
The penetration is a fraction of the first candle’s real body. TA-Lib’s default is 0.5. A penetration of 0 asks only for a close below the first close; values above 1 are valid, although in exact arithmetic the pattern cannot fire at 1 or more, since the close would then have to be below the first open while above it; the rounded line can lie a few ulps above the first open at a penetration of 1 or within rounding of it, and a close between the two then fires, as in TA-Lib 0.6.4. A negative, NaN or infinite penetration gives zeros of the receiver’s length. Lengths are checked before penetration.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o, h and c at bar t-1, o and c at bar t, and BodyLong at bar t-1. Bars before TA-Lib’s lookback, the first 11, are 0.
CandlePiercing is the bullish counterpart but not an exact mirror: its fraction is fixed at 0.5, it asks for a long second body, and it compares the open with the prior low. TA-Lib does not test the trend: a dark cloud cover is a top reversal only after an advance, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleDoji
func (s Series) CandleDoji(o, h, l Series) Series
CandleDoji is 1 on a doji, a real body no larger than a tenth of the mean range of the previous ten bars (TA-Lib CDLDOJI), and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleDoji(o, h, l). Bar t is 1 when its real body |c - o| is at most BodyDoji at bar t, an inclusive test, and 0 otherwise. The setting BodyDoji (CandleHighLow, 10, 0.1) is a tenth of the mean of h - l over bars t-10 to t-1. The 1 means that a doji is present, not that it is bullish: a doji marks indecision, and its meaning depends on the trend before it; TA-Lib does not test the trend, so the caller supplies that context. Ten or more flat bars give a BodyDoji of 0, and every zero body from bar 10 on is then a doji, since the test is inclusive.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a body sits on a tie that the two sums round differently. On any table without an infinite threshold the result is c.RealBody(o).LTE(c.CandleAverage(o, h, l, CandleHighLow, 10, 0.1)) bit for bit, NaN included, since LTE gives 0 where either operand is NaN; where a window holds an infinite range the two differ, LTE giving 1 for a finite body and this method 0.
It reads o and c at bar t and BodyDoji at bar t. Bars before TA-Lib’s lookback, the first 10, are 0.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleEngulfing
func (s Series) CandleEngulfing(o, h, l Series) Series
CandleEngulfing is 1 for a bullish and -1 for a bearish engulfing pattern, 0.8 or -0.8 when the two real bodies match at one end (TA-Lib CDLENGULFING), and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleEngulfing(o, h, l). A candle is white when c >= o, a tie counting as white as in TA-Lib, and black otherwise. Bar t is a bullish engulfing when it is white, bar t-1 is black, and either c[t] >= o[t-1] with o[t] < c[t-1] or c[t] > o[t-1] with o[t] <= c[t-1]; it is a bearish one when it is black, bar t-1 is white, and either o[t] >= c[t-1] with c[t] < o[t-1] or o[t] > c[t-1] with c[t] <= o[t-1]. The value is 1 or -1 when o[t] != c[t-1] and c[t] != o[t-1], and 0.8 or -0.8 when the bodies match at one end, TA-Lib’s 80 divided by 100. Bodies equal at both ends satisfy neither arm and give 0, as does any other bar. TA-Lib before 0.6.0 had no one-end tie and gave 0 on those bars. For a result x, x.GT(0).Sub(x.LT(0)) is its sign, the ties folded into 1 and -1, and x.Abs().EQ(1) marks the full patterns only.
The first candle may be a doji: with c = o it is white in TA-Lib’s convention, so it can be engulfed by a black candle and not by a white one. On every other bar the pattern is its own mirror on reflected prices, o, h, l and c negated with the high and the low swapped, bit for bit. TA-Lib does not test the trend: a bullish engulfing is a reversal signal only after a decline and a bearish one only after an advance, which the caller supplies.
It reads o and c at bars t-1 and t, and no threshold. Bars before TA-Lib’s lookback, the first 2, are 0. On finite prices the method equals TA-Lib 0.6.4, its integer output divided by 100, bit for bit.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers, so there an infinite close is a white candle that can engulf. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives the same values from its own lookback on, bit for bit.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned, and the high and the low are checked but not read. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleEveningStar
func (s Series) CandleEveningStar(o, h, l Series, penetration float64) Series
CandleEveningStar is -1 on TA-Lib’s evening star (CDLEVENINGSTAR), a long white candle, a short body gapping up and a black candle closing more than penetration times the first body below the first close, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleEveningStar(o, h, l, 0.3). Bar t is -1 when bar t-2 is white, c >= o, with a real body |c - o| above BodyLong at bar t-2, bar t-1 has a body at most BodyShort at bar t-1 and gaps up, min(o, c) at bar t-1 above max(o, c) at bar t-2, and bar t is black, c < o, with a body above BodyShort at bar t, longer than short, and c[t] < c[t-2] - penetration times the first body, the product rounded before the subtraction as in TA-Lib 0.6.4; otherwise it is 0. Only the star’s body test is inclusive. The settings are BodyLong (CandleRealBody, 10, 1) and BodyShort (CandleRealBody, 10, 1), each the mean body of the ten bars before the bar it is read at, so the two series are equal.
The penetration is a fraction of the first candle’s real body. TA-Lib’s default is 0.3. A penetration of 0 asks only for a close below the first close; values above 1 are valid and ask for a close below the first open, since there is no lower test. A negative, NaN or infinite penetration gives zeros of the receiver’s length. Lengths are checked before penetration.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o and c at bars t-2 to t, BodyLong at bar t-2, and BodyShort at bars t-1 and t. Bars before TA-Lib’s lookback, the first 12, are 0.
CandleMorningStar is the exact mirror: on reflected prices, o, h, l and c negated with the high and the low swapped, the negated CandleMorningStar is this method bit for bit at every penetration, as in TA-Lib 0.6.4. TA-Lib 0.8.1 fuses the morning star’s line into a multiply-add and not this one’s, so there the two stars are not exact mirrors; this method and the line it mirrors keep separate products, as 0.6.4 has them. TA-Lib does not test the trend: an evening star is a top reversal only after an advance, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleHammer
func (s Series) CandleHammer(o, h, l Series) Series
CandleHammer is 1 on TA-Lib’s hammer (CDLHAMMER), a small real body near or below the prior bar’s low with a long lower shadow and a very short upper shadow, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleHammer(o, h, l). Bar t is 1 when its real body |c - o| is below BodyShort at bar t, its lower shadow min(o, c) - l is above ShadowLong at bar t, its upper shadow h - max(o, c) is below ShadowVeryShort at bar t, and min(o, c) <= l[t-1] + Near at bar t-1, the body ending at or below a band above the prior low; otherwise it is 0. The three size tests are strict and the band is inclusive. The settings are BodyShort (CandleRealBody, 10, 1), the mean body of bars t-10 to t-1, ShadowLong (CandleRealBody, 0, 1), the body of bar t itself, so the lower shadow must be longer than the body where Nison asks for at least twice it, ShadowVeryShort (CandleHighLow, 10, 0.1), a tenth of the mean range of bars t-10 to t-1, and Near (CandleHighLow, 5, 0.2), a fifth of the mean range of bars t-6 to t-2. A caller who wants Nison’s stricter shadow can multiply the result by c.LowerShadow(o, l).GT(c.RealBody(o).Mul(2)).
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o, h, l and c at bar t, l at bar t-1, BodyShort, ShadowLong and ShadowVeryShort at bar t, and Near at bar t-1. Bars before TA-Lib’s lookback, the first 11, are 0.
CandleHangingMan tests the same bar against the prior high, so the two share their first three tests and fire together only when the prior range h[t-1] - l[t-1] is at most twice Near at bar t-1, to rounding. TA-Lib does not test the trend: a hammer is a bottom reversal only after a decline, which the caller supplies, for instance as c.CandleHammer(o, h, l).Mul(c.LT(c.Average(20))) after Sung.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleHangingMan
func (s Series) CandleHangingMan(o, h, l Series) Series
CandleHangingMan is -1 on TA-Lib’s hanging man (CDLHANGINGMAN), a small real body near or above the prior bar’s high with a long lower shadow and a very short upper shadow, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleHangingMan(o, h, l). Bar t is -1 when its real body |c - o| is below BodyShort at bar t, its lower shadow min(o, c) - l is above ShadowLong at bar t, its upper shadow h - max(o, c) is below ShadowVeryShort at bar t, and min(o, c) >= h[t-1] - Near at bar t-1, the body ending at or above a band below the prior high; otherwise it is 0. The three size tests are strict and the band is inclusive. The settings are BodyShort (CandleRealBody, 10, 1), the mean body of bars t-10 to t-1, ShadowLong (CandleRealBody, 0, 1), the body of bar t itself, so the lower shadow must be longer than the body where Nison asks for at least twice it, ShadowVeryShort (CandleHighLow, 10, 0.1), a tenth of the mean range of bars t-10 to t-1, and Near (CandleHighLow, 5, 0.2), a fifth of the mean range of bars t-6 to t-2.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o, h, l and c at bar t, h at bar t-1, BodyShort, ShadowLong and ShadowVeryShort at bar t, and Near at bar t-1. Bars before TA-Lib’s lookback, the first 11, are 0.
CandleHammer tests the same bar against the prior low, so the two share their first three tests and fire together only when the prior range h[t-1] - l[t-1] is at most twice Near at bar t-1, to rounding. TA-Lib does not test the trend: a hanging man is a top reversal only after an advance, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleHarami
func (s Series) CandleHarami(o, h, l Series) Series
CandleHarami is 1 after a long black candle and -1 after a long white one when a short real body lies inside it, 0.8 or -0.8 when the bodies match at one end (TA-Lib CDLHARAMI), and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleHarami(o, h, l). Bar t is tested when the real body |c - o| of bar t-1 is above BodyLong at bar t-1, a strict test, and the body of bar t is at most BodyShort at bar t, an inclusive one. The value is then 1 or -1 when max(o, c) at bar t is below max(o, c) at bar t-1 and min(o, c) at bar t is above min(o, c) at bar t-1, the second body strictly inside the first, and 0.8 or -0.8, TA-Lib’s 80 divided by 100, when the two inclusive tests hold instead, the bodies matching at one end; otherwise, and on every other bar, it is 0. The sign is against the first candle’s colour: negative after a white candle, c >= o at bar t-1, and positive after a black one. The colour of the second candle is not tested, so it may be a doji; the first cannot be, since its body exceeds a threshold that is not negative, so the white tie does not arise. TA-Lib before 0.6.0 had no one-end tie and gave 0 on those bars. For a result x, x.GT(0).Sub(x.LT(0)) is its sign, the ties folded into 1 and -1, and x.Abs().EQ(1) marks the full patterns only. The settings are BodyLong (CandleRealBody, 10, 1) and BodyShort (CandleRealBody, 10, 1), each the mean body of the ten bars before the bar it is read at, so the two series are equal.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o and c at bars t-1 and t, BodyLong at bar t-1 and BodyShort at bar t. Bars before TA-Lib’s lookback, the first 11, are 0.
The pattern is its own mirror on reflected prices, o, h, l and c negated with the high and the low swapped, bit for bit. TA-Lib does not test the trend: a harami is a reversal signal only against the trend before it, a bullish one after a decline and a bearish one after an advance, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleInvertedHammer
func (s Series) CandleInvertedHammer(o, h, l Series) Series
CandleInvertedHammer is 1 on TA-Lib’s inverted hammer (CDLINVERTEDHAMMER), a small real body gapping down from the prior body with a long upper shadow and a very short lower shadow, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleInvertedHammer(o, h, l). Bar t is 1 when its real body |c - o| is below BodyShort at bar t, its upper shadow h - max(o, c) is above ShadowLong at bar t, its lower shadow min(o, c) - l is below ShadowVeryShort at bar t, and its body gaps down from the prior body, max(o, c) at bar t below min(o, c) at bar t-1; otherwise it is 0. Every test is strict. The settings are BodyShort (CandleRealBody, 10, 1), the mean body of bars t-10 to t-1, ShadowLong (CandleRealBody, 0, 1), the body of bar t itself, so the upper shadow must be longer than the body, and ShadowVeryShort (CandleHighLow, 10, 0.1), a tenth of the mean range of bars t-10 to t-1.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o, h, l and c at bar t, o and c at bar t-1, and BodyShort, ShadowLong and ShadowVeryShort at bar t. Bars before TA-Lib’s lookback, the first 11, are 0.
CandleShootingStar is the same shape gapping up, and the two do not fire on the same bar, since their gaps are opposite and strict. TA-Lib does not test the trend: an inverted hammer is a bottom reversal only after a decline, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleMorningStar
func (s Series) CandleMorningStar(o, h, l Series, penetration float64) Series
CandleMorningStar is 1 on TA-Lib’s morning star (CDLMORNINGSTAR), a long black candle, a short body gapping down and a white candle closing more than penetration times the first body above the first close, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleMorningStar(o, h, l, 0.3). Bar t is 1 when bar t-2 is black, c < o, with a real body |c - o| above BodyLong at bar t-2, bar t-1 has a body at most BodyShort at bar t-1 and gaps down, max(o, c) at bar t-1 below min(o, c) at bar t-2, and bar t is white, c >= o, with a body above BodyShort at bar t, longer than short, and c[t] > c[t-2] + penetration times the first body, the product rounded before the addition as in TA-Lib 0.6.4; otherwise it is 0. Only the star’s body test is inclusive. The settings are BodyLong (CandleRealBody, 10, 1) and BodyShort (CandleRealBody, 10, 1), each the mean body of the ten bars before the bar it is read at, so the two series are equal.
The penetration is a fraction of the first candle’s real body. TA-Lib’s default is 0.3. A penetration of 0 asks only for a close above the first close; values above 1 are valid and ask for a close above the first open, since there is no upper test. A negative, NaN or infinite penetration gives zeros of the receiver’s length. Lengths are checked before penetration.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o and c at bars t-2 to t, BodyLong at bar t-2, and BodyShort at bars t-1 and t. Bars before TA-Lib’s lookback, the first 12, are 0.
CandleEveningStar is the exact mirror: on reflected prices, o, h, l and c negated with the high and the low swapped, the negated CandleEveningStar is this method bit for bit at every penetration, as in TA-Lib 0.6.4. TA-Lib 0.8.1 writes this method’s line as a fused multiply-add, which can move it by one ulp, so a close exactly on the 0.6.4 line can differ there, and the two stars are then not exact mirrors; this method keeps the rounding of 0.6.4. TA-Lib does not test the trend: a morning star is a bottom reversal only after a decline, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandlePiercing
func (s Series) CandlePiercing(o, h, l Series) Series
CandlePiercing is 1 on TA-Lib’s piercing pattern (CDLPIERCING), a long white candle that opens below the low of a long black candle and closes inside its body, above the midpoint, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandlePiercing(o, h, l). Bar t is 1 when bar t-1 is black, c < o, with a real body |c - o| above BodyLong at bar t-1, bar t is white, c >= o, with a body above BodyLong at bar t, o[t] < l[t-1], c[t] < o[t-1] and c[t] > c[t-1] + 0.5 times the first body, the product rounded before the addition as in TA-Lib 0.6.4; otherwise it is 0. Every test is strict. The fraction of the first body is fixed at 0.5, as in TA-Lib, which has no penetration parameter here, and the second body must be long too. The setting BodyLong (CandleRealBody, 10, 1) is the mean body of the ten bars before the bar it is read at. TA-Lib 0.8.1 writes the midpoint line as a fused multiply-add; the product by 0.5 is exact unless the first body is subnormal, so the two agree on all practical data.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o, l and c at bar t-1, o and c at bar t, and BodyLong at bars t-1 and t. Bars before TA-Lib’s lookback, the first 11, are 0.
CandleDarkCloudCover is the bearish counterpart but not an exact mirror: it takes a penetration, has no size test on its second candle, and compares the open with the prior high. TA-Lib does not test the trend: a piercing pattern is a bottom reversal only after a decline, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleShootingStar
func (s Series) CandleShootingStar(o, h, l Series) Series
CandleShootingStar is -1 on TA-Lib’s shooting star (CDLSHOOTINGSTAR), a small real body gapping up from the prior body with a long upper shadow and a very short lower shadow, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleShootingStar(o, h, l). Bar t is -1 when its real body |c - o| is below BodyShort at bar t, its upper shadow h - max(o, c) is above ShadowLong at bar t, its lower shadow min(o, c) - l is below ShadowVeryShort at bar t, and its body gaps up from the prior body, min(o, c) at bar t above max(o, c) at bar t-1; otherwise it is 0. Every test is strict. The settings are BodyShort (CandleRealBody, 10, 1), the mean body of bars t-10 to t-1, ShadowLong (CandleRealBody, 0, 1), the body of bar t itself, so the upper shadow must be longer than the body, and ShadowVeryShort (CandleHighLow, 10, 0.1), a tenth of the mean range of bars t-10 to t-1.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o, h, l and c at bar t, o and c at bar t-1, and BodyShort, ShadowLong and ShadowVeryShort at bar t. Bars before TA-Lib’s lookback, the first 11, are 0.
CandleInvertedHammer is the same shape gapping down, and the two do not fire on the same bar, since their gaps are opposite and strict. TA-Lib does not test the trend: a shooting star is a top reversal only after an advance, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleThreeBlackCrows
func (s Series) CandleThreeBlackCrows(o, h, l Series) Series
CandleThreeBlackCrows is -1 on TA-Lib’s three black crows (CDL3BLACKCROWS), a white candle and then three falling black candles with very short lower shadows, each opening inside the prior body, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleThreeBlackCrows(o, h, l). Bar t is -1 when bar t-3 is a white candle, c >= o, a doji counting as white, bars t-2, t-1 and t are each black, c < o, with a lower shadow min(o, c) - l below ShadowVeryShort at their own bar, each crow opens inside the prior crow’s body, o[t-1] < o[t-2] with o[t-1] > c[t-2] and o[t] < o[t-1] with o[t] > c[t-1], the first crow closes below the white candle’s high, h[t-3] > c[t-2], and the closes fall, c[t-2] > c[t-1] > c[t]; otherwise it is 0. Every test is strict. There is no body-size, Near or Far test, unlike the soldiers. The setting ShadowVeryShort (CandleHighLow, 10, 0.1) is a tenth of the mean range of the ten bars before the bar it is read at.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o, h and c at bar t-3, o, l and c at bars t-2 to t, and ShadowVeryShort at bars t-2 to t. Bars before TA-Lib’s lookback, the first 13, are 0.
CandleThreeWhiteSoldiers is the bullish counterpart but not an exact mirror: it has Near, Far and body-size tests and no test of the candle before the three. TA-Lib does not test the trend: three black crows are a top reversal only after an advance, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
CandleThreeWhiteSoldiers
func (s Series) CandleThreeWhiteSoldiers(o, h, l Series) Series
CandleThreeWhiteSoldiers is 1 on TA-Lib’s three white soldiers (CDL3WHITESOLDIERS), three white candles with rising opens and closes and very short upper shadows, each opening inside or near the prior body, and 0 otherwise.
The receiver is the close, written c below, so a caller writes c.CandleThreeWhiteSoldiers(o, h, l). Bar t is 1 when bars t-2, t-1 and t are each white, c >= o, with an upper shadow h - max(o, c) below ShadowVeryShort at their own bar, the closes rise, c[t] > c[t-1] > c[t-2], the opens rise, o[t-1] > o[t-2] and o[t] > o[t-1], each open is inside or near the prior body, o[t-1] <= c[t-2] + Near at bar t-2 and o[t] <= c[t-1] + Near at bar t-1, no body is far shorter than the one before it, |c - o| at bar t-1 above |c - o| at bar t-2 less Far at bar t-2 and |c - o| at bar t above |c - o| at bar t-1 less Far at bar t-1, and the third body is above BodyShort at bar t; otherwise it is 0. The Near bands are inclusive and every other test is strict. Only the third body is tested against BodyShort, as in TA-Lib’s code, whose comment asks for all three; a doji soldier, c = o, counts as white. The settings are ShadowVeryShort (CandleHighLow, 10, 0.1), a tenth of the mean range of the ten bars before the bar it is read at, Near (CandleHighLow, 5, 0.2) and Far (CandleHighLow, 5, 0.6), a fifth and six tenths of the mean range of the five bars before, and BodyShort (CandleRealBody, 10, 1), the mean body of bars t-10 to t-1.
Each threshold is c.CandleAverage(o, h, l, kind, n, factor) at TA-Lib’s default setting, bit for bit; it agrees with TA-Lib’s running total to rounding, and exactly where the window sums are exact, as on prices in quarters. So the method equals TA-Lib 0.6.4, its integer output divided by 100, except where a compared value sits on a tie that the two sums round differently.
It reads o, h and c at bars t-2 to t, ShadowVeryShort at bars t-2 to t, Near and Far at bars t-2 and t-1, and BodyShort at bar t. Bars before TA-Lib’s lookback, the first 12, are 0.
CandleThreeBlackCrows is the bearish counterpart but not an exact mirror: it asks for a white candle before the three and has no Near, Far or body-size test. TA-Lib does not test the trend: three white soldiers are a bottom reversal only after a decline, which the caller supplies.
A bar whose decision reads a NaN, +Inf or -Inf, among its prices or through the window of a threshold, is 0, and later bars recover once the value has left the windows. TA-Lib compares infinities as numbers and keeps a NaN running total to the end of the call. A caller who wants missing bars to stay missing can mask the result with MaskNonFinite. A table that starts later gives, from its own lookback on, the same values, bit for bit where the window sums are exact and otherwise to rounding.
The open o, high h and low l must each have the receiver’s length, otherwise the result is Series{}. They are the columns of one bar table, so they are not right-aligned. The cost is O(len(s)); the result is fresh storage and the inputs are not modified.
LowerShadow
func (s Series) LowerShadow(o, l Series) Series
LowerShadow returns each candle’s lower shadow, the lesser of the open o and the receiver’s close less the low l.
With close c as the receiver, each bar is min(o[t], c[t]) - l[t], using built-in min. The body bottom is c.Minimum(o), so c.Minimum(o).Sub(l) gives the same result bit for bit. NaN in any input gives NaN, and infinities follow IEEE subtraction; +Inf minus +Inf is NaN. The built-in selects -0 from +0 and -0, and the subtraction preserves IEEE signed zeros.
TA-Lib’s TA_LOWERSHADOW uses c >= o to choose the body’s bottom. That selection differs when the open is NaN, where it reads the close, and for a close of -0 with an open of +0. Prices are unchecked; a low above the body gives a negative shadow.
Upper shadow plus lower shadow plus real body, in that order, equals h.Sub(l) exactly on well-formed bars with 0 < l and h <= 2l, and on prices in quarters; it agrees to rounding otherwise.
The open and low must each have the receiver’s length, otherwise the result is Series{}. These are columns of one bar table and are not right-aligned. Empty or nil inputs of matching length give an empty, non-nil result. There is no warm-up: the first valid index is 0. The method takes one pass, returns fresh storage and does not modify its inputs.
RealBody
func (s Series) RealBody(o Series) Series
RealBody returns the size of each candle’s real body, the absolute difference between the receiver’s close and the open o.
With close c as the receiver, the value at bar t is |c[t] - o[t]|, TA-Lib’s TA_REALBODY, and equals c.Sub(o).Abs() bit for bit. A tie of finite values gives +0, including either order of +0 and -0, because the absolute value clears the sign. A NaN in either input gives NaN. Infinities follow IEEE arithmetic: an infinite difference gives +Inf, and subtracting the same infinity gives NaN.
The signed body is c.Sub(o); its n-bar average agrees with QStick(o, c, n) to rounding. The candle’s colour is c.GTE(o): 1 for white and 0 for black, with a tie counting as white.
Upper shadow plus lower shadow plus real body, in that order, equals h.Sub(l) exactly on well-formed bars with 0 < l and h <= 2l, and on prices in quarters; it agrees to rounding otherwise.
The open must have the receiver’s length, otherwise the result is Series{}. These are columns of one bar table and are not right-aligned. Empty or nil inputs of matching length give an empty, non-nil result. There is no warm-up: the first valid index is 0. The method takes one pass, returns fresh storage and does not modify its inputs.
UpperShadow
func (s Series) UpperShadow(o, h Series) Series
UpperShadow returns each candle’s upper shadow, the high h less the greater of the open o and the receiver’s close.
With close c as the receiver, each bar is h[t] - max(o[t], c[t]), using built-in max. The body top is c.Maximum(o), so h.Sub(c.Maximum(o)) gives the same result bit for bit. NaN in any input gives NaN, and infinities follow IEEE subtraction; +Inf minus +Inf is NaN. The built-in selects +0 from +0 and -0, and the subtraction preserves IEEE signed zeros.
TA-Lib’s TA_UPPERSHADOW uses c >= o to choose the body’s top. That selection differs when the close is NaN, where it reads the open, and for a close of -0 with an open of +0. Prices are unchecked; a high below the body gives a negative shadow.
Upper shadow plus lower shadow plus real body, in that order, equals h.Sub(l) exactly on well-formed bars with 0 < l and h <= 2l, and on prices in quarters; it agrees to rounding otherwise.
The open and high must each have the receiver’s length, otherwise the result is Series{}. These are columns of one bar table and are not right-aligned. Empty or nil inputs of matching length give an empty, non-nil result. There is no warm-up: the first valid index is 0. The method takes one pass, returns fresh storage and does not modify its inputs.
Compositions
Andrea Unger’s indecision filter allows entries on a day after an indecisive one, a day whose body, the distance from open to close (RealBody), was less than a fraction of its range, and his weekly factor applies the same test to the five sessions before. Recipe values (the daily and weekly factors) are NaN before their first valid index (SetN(F, math.NaN())), and the gates read 0 there, closed: every shifted series a pad can satisfy is masked, or the gate is. Prices are positive and finite and the bars are the caller’s daily bars, one a session (Unger trades 15- and 30-minute bars, which the intraday variant of the first section reaches only through a session flag); series are paired by position, so the caller aligns them by timestamp first. Both recipes read the open o. The gates place no order: Unger’s breakout stops, session windows and exits on the close belong to the caller’s model. An exact decimal tie of a body with a fraction of a range is decided by binary rounding, first of the price differences: the page pins the division-free comparison for the gates and Div for the factors, the two agree for a fraction that is a power of two, and the goldens run on prices in sixty-fourths, where ties are exact. Unger’s backtests are over data we do not have: evidence, not a reference.
Indecision gate and daily factor (Unger)
Andrea Unger (“Filters On The Test Bench”, Stocks & Commodities V40:12, November 2022, pp. 12-15) calls the market “indecisive” “If at the end of the session the distance between start and finish is less than 50% of the whole excursion”, and his Figure 2 listing tests the prior session division-free and strictly, absvalue(opens(1)-closes(1)) < myfactor*(highs(1)-lows(1)), so a flat session (H = L) is not indecisive. In “The Daily Factor: A Volatility Filter” (Stocks & Commodities V41:7, June 2023, pp. 26-31) he divides, “DF = Body / Range”, and assigns the DF only if (highS(1) - lowS(1)) <> 0, so the last DF is kept over a flat session. t6IndecisionGate returns the 2022 gate gate, the canonical form, the prior session’s daily factor df with the 2023 carry rule and the 2023 gate gate5275.
gate := c.RealBody(o).LT(h.Sub(l).Mul(f)).Shift(1)
dfc := c.RealBody(o).Div(h.Sub(l)).ValueWhen(h.GT(l))
df := dfc.Shift(1).SetN(1, math.NaN())
gate5275 := dfc.LT(f).Shift(1)- Inputs: daily opens, highs, lows and closes; f the fraction of the range: 0.5 for his “pattern 1”, 0.35 in 2023 (“which maximizes profits and shows stable results in its neighborhood”) and 0.4 to 0.9 in his later articles. An f above 1 disables
gate(his default is 2) except after a flat bar, which still closes it; at f = 1 the strict<still blocks the day after a session whose DF is exactly 1, its open and close at the extremes. - First valid index: 1 for all three:
gateandgate5275read 0, closed, on bar 0 (theShiftpad) anddfis NaN there; before the first bar with a rangedfis NaN andgate5275reads 0, andgatealso reads 0 after a flat bar or a bar with a NaN.gateis window-local (one prior bar); the carry makesdfandgate5275latch over any run of flat bars. - Anchors:
gateequalsc.RealBody(o).LT(c.CandleAverage(o, h, l, CandleHighLow, 0, f)).Shift(1)bit for bit (with n = 0CandleAverageis f times the bar’s own range) and a loop of Figure 2’s pattern line;dfcequals a loop of the 2023 listing from the first bar with a range. |BOP| = DF for h >= l: TA-Lib’s Balance of Power,(Close - Open)/(High - Low)and 0 for a range at or below 0, has no method here, andc.Sub(o).Div(h.Sub(l)).Abs()equalsc.RealBody(o).Div(h.Sub(l))bit for bit. The seven-bar witness (o 5, 5, 5, 4.5, 4.25, 4.25, 4; h 5, 5, 5.5, 5, 4.5, 4.25, 4.5; l 5, 5, 4.5, 4.25, 4, 4.25, 3.5; c 5, 5, 5.25, 4.25, 4.25, 4.25, 4.25; bars 0, 1 and 5 flat; f 0.5) gives the canonicalgate[0 0 0 1 1 1 0], the 2023 gate [0 0 0 1 1 1 1] anddf[NaN NaN NaN 0.25 0.3333333333333333 0 0]. For f a power of two the division and division-free forms agree; at decimal ties for f such as 0.35 or 0.7 they can differ (O 1.00, H 4.00, L 1.00, C 2.05 at 0.35: the DF 0.3499999999999999 is below 0.35, while the product test 1.0499999999999998 < 1.0499999999999998 fails). - Traps: the bare-
Divgate,c.RealBody(o).Div(h.Sub(l)).LT(0.5).Shift(1), reads a flat session’s DF of 0 as maximum indecision and opens: [0 1 1 1 1 1 1] on the seven bars, a reading no Unger listing has. The dossier’sdf.Shift(1).LT(f)compares the +0 pad and opens bar 0, and its “Unger keeps the previous DF” holds from 2023 on: the 2022 listing is division-free and keeps nothing. HisVar: DF(0)starts at 0, so his 2023 gate is open before the first session with a range, wheregate5275is closed (a start-of-data difference). NoBalanceOfPoweris shipped (the signed ratioc.Sub(o).Div(h.Sub(l))is the QStick compositions’ balance of power), andCandleDojiis another test, inclusive and against the average range of earlier bars. It isc.RealBody(o).LTE(c.CandleAverage(o, h, l, CandleHighLow, 10, 0.1)), soc.CandleDoji(o, h, l).Shift(1)isgatewith f = 0.1,LTEforLTand the mean range of the ten bars before for the bar’s own range. - Variant: intraday bars from the caller’s session-start flag
sf(1 on each session’s first bar), in one line: withev := sf.SetN(1, 0)the prior session’s close, high, low and open arec.Shift(1).ValueWhen(ev),h.HighestSince(sf).Shift(1).ValueWhen(ev),l.LowestSince(sf).Shift(1).ValueWhen(ev)ando.ValueWhen(sf).Shift(1).ValueWhen(ev), and the gate is the canonical comparison of them, equal to a loop that aggregates the sessions (402 bars in 58 sessions). - Missing piece: the session-start flag itself, which needs timestamps: the missing piece “holding a daily value on intraday bars” of the Average Directional Index page
t6-directional-index.md(“ADX environments and the rising-ADX gate”), whose step “applies the last completed session’s value to the next session’s bars” the variant writes out. NoPriorPeriod*method is shipped, and the open composes as above. - Evidence: the 2022 article’s four futures on 15-minute bars from 2010 (DAX, crude oil, gold and the E-mini S&P 500), each with a random series as a control, costs not stated: f 0.5 against 2 (off) cut the trades by about half and raised the average trade on all four markets (DAX 48.36 to 63.96, gold 41.93 to 88.47), and on the random series it lowered the DAX’s and crude’s but raised gold’s and the E-mini’s (32.33 to 38.68), though the text says of the E-mini that the filter “has no effect on randomized data”. The 2023 article (crude oil on 30-minute bars from 2010, a 40-bar channel, no stop) chose 0.35 from its Figure 5 sweep, in sample (net profit is higher at 0.65), and its level-0 row has no trade, as the strict
<requires. Evidence, not a reference. - Pinned by
TestRecipeT6IndecisionGate; runnable exampleExampleSeries_RealBody_indecisionGate.
Weekly factor (Unger)
Unger’s “The Weekly Factor Pattern” (Stocks & Commodities V41:9, August 2023, pp. 14-17) “looks at the trading range in a trading week (that is, the highest high and the lowest low of the last five sessions) and then compares that to the open of the session five days ago and the close of the session one day ago”; his strategy listing (p. 15) tests AbsValue(OpenS(5) - CloseS(1)) < RangeFilter * (maxlist(highS(1), ..., highS(5)) - minlist(lowS(1), ..., lowS(5))), strict and division-free. t6WeeklyFactor returns the factor wfac, the five-session body over the five-session range of the bars before t, and the gate wgate.
wbody := c.Shift(1).RealBody(o.Shift(5))
wrange := h.Highest(5).Sub(l.Lowest(5)).Shift(1)
wfac := wbody.Div(wrange).SetN(5, math.NaN())
wgate := wbody.LT(wrange.Mul(wf)).SetN(5, 0)- Inputs: daily opens, highs, lows and closes, one bar a session (his strategy runs on 15-minute bars); wf 0.7 (“This value of 0.7 means that the body should be less than 70% of the total weekly range”), 0.85 in a later article (Stocks & Commodities V44:7, July 2026); his Figure 1’s 50% is a schematic label.
- First valid index: 5 for both:
wfacis NaN andwgatereads 0 on bars 0 to 4, whereo.Shift(5)is the pad and the windows are still expanding. TheSetN(5, 0)ofwgateis needed: on bars 1 to 4 the padded open and the expanding range can pass the test (highs 10, lows 1, opens and closes 2 fire there unmasked), which a constructed case pins. - Anchors: the body is |O[t-5] - C[t-1]| and the range the highest high less the lowest low of bars t-5 to t-1, the current bar excluded;
wgateequals a loop of the strategy line bit for bit from bar 5, and the dossier’s rangeh.Shift(1).Highest(5).Sub(l.Shift(1).Lowest(5))gives the same gate after the mask (the two ranges differ only on bars 1 to 4, where the pad entersLowest). A five-session window with H = L everywhere reads closed, andwfacis 0 there. The strict<is pinned by a constructed case: a range of 20 ticks with a body of 14 ties the gate at 0.7. - Traps: the p. 14 text expression,
AbsValue(OpenS(5) - CloseS(1)) < RangeFilter * maxlist(...) - minlist(...), lacks the brackets the strategy line has, so it reads wf times the highest high less the lowest low; the recipe takes the bracketed line. The dossier’swf.LT(0.7)on the quotient reads a flat five-session window (a factor of 0, byDiv’s zero rule) as open, unlike the listing’s division-free test. - Evidence: his Figure 4 (three metals on 15-minute bars, RangeFilter swept from 0.1 to 1) has 9,872 trades at 1 and 7,904 at 0.7 (“about 2,000 trades (20%) are filtered out”), whose average trades Figures 3 and 6 give as 20.56 and 30.03; net profit peaks at 0.8 (253,750) while the text picks 0.7 for its drawdown, in sample, and the RangeFilter 0 row has no trade, as the strict
<requires. Evidence, not a reference. - Pinned by
TestRecipeT6WeeklyFactor.