DeMark Indicators

All functions · nseries package

TD Sequential’s setup phase

“TD Sequential”, “TD Setup”, “TD Price Flip”, “TDST” and the other TD names are trademarks of DeMark Analytics LLC (formerly Market Studies LLC), used here only to name the indicators; the methods’ names are descriptive (DeMarkSetup and so on).

These methods are the first half of Tom DeMark’s TD Sequential: the price flip, the setup count, setup perfection and the TDST levels, built on the true high and true low (TrueHigh and TrueLow, under “True Range”). The rulebook is Jason Perl’s DeMark Indicators (Bloomberg Press, 2008), chapter 1, with the Bloomberg default settings: a setup of at least 9 bars, a look-back of 4 bars and the close as the setup price, with the setup option “Include Prior Four Bars” off; TDST on, with its options “Extend the 2nd Most Recent TDST Level” and “Open Restriction” off. The three options are not built. DeMark’s 1994 rulebook (The New Science of Technical Analysis, as Davies applied it in 1995), with a non-strict flip and an “intersection” test in place of perfection, is a different indicator and is not built.

  • DeMarkPriceFlip marks the flips: a bearish flip is a close above the close four bars earlier followed at once by a close below the close four bars earlier, and a bullish flip is the mirror. Both comparisons are strict.
  • DeMarkSetup is the signed setup count. A buy setup starts on a bearish flip, its bar 1, and runs while each close is strictly below the close four bars earlier; it reads -1, -2 and so on. A sell setup mirrors it with +1, +2 and so on. Bar 9 completes a setup, and the count runs on past 9 until the run ends.
  • DeMarkSetupPerfected reports whether the most recently completed setup is perfected: -1 for a buy, +1 for a sell, and 0 while perfection is deferred.
  • DeMarkSetupResistance and DeMarkSetupSupport are the TDST levels: the highest true high of bars 1 to 9 of the most recently completed buy setup, and the lowest true low of bars 1 to 9 of the most recently completed sell setup, each held until the next completion of its side.

The setup count is the whole state of the setup phase: the three views read it, and each runs it again. A tie or a comparison with NaN ends a run, and +Inf and -Inf are ordinary values. The flip, the count and the perfection read 0 before their first event; the levels read NaN until the first completed setup of their side. Each method’s doc gives its rules in full. Under a slice of history the count settles at the first flip inside the slice and the levels at the first completion of their side, so give the methods a few hundred bars.

Evidence. Perl writes that he has not backtested the signals (“I have not felt the need to backtest the signals”, p. 48), and the book gives no trade statistics. Coles (2011) and Davies (1995) give single charts or hand-picked trades. The sources offer chart examples only; no backtest supports these signals.

The second phase. TD Sequential’s countdown, with its qualifiers, cancellation, recycling and the R of an 18-bar setup, TD Aggressive Sequential, TD Combo and the risk levels read the count of DeMarkSetup; they follow the setup recipes below.

Setup recipes

The blocks share their names: c, h and l are the closes, highs and lows, k comes from the first block and res and sup from the second.

Completion and display. Each setup completes once, on its bar 9, and bar 13 is the first bar that can complete one. Charting systems show bars 1 to 9 only.

k := c.DeMarkSetup()
buy9 := k.EQ(-9)          // 1 on bar 9 of each buy setup, its completion bar
sell9 := k.EQ(9)          // 1 on bar 9 of each sell setup
display := k.Clamp(-9, 9) // the count as charting systems show it

Trend bias (Perl’s two scenarios, pp. 6-8). In Scenario I, consolidation or reversal, no close up to and including bar 9 of the active setup is beyond the TDST level of the most recently completed setup in the opposite direction: the market lacks the momentum to break out of the range, and Perl expects a reversal or at least a consolidation lasting a minimum of one to four bars. In Scenario II, confirmed trend extension, a close beyond that level shows the momentum for a sustained break. Only closes count: a break within a bar does not.

res := c.DeMarkSetupResistance(h)
sup := c.DeMarkSetupSupport(l)
bias := c.GT(res).Sub(c.LT(sup)) // +1 above resistance, -1 below support, 0 otherwise

A comparison with a NaN level is false, so a side with no completed setup yet adds nothing, and a NaN close reads 0. The levels come from different setups and can cross: a close above the resistance and below the support at once reads 0.

Setup trade filter (Perl, pp. 13 and 16). Perl trades a completed buy setup only when it is perfected and none of its nine bars has closed below TDST support, and a sell setup only when it is perfected and none has closed above TDST resistance: Scenario I on the setup’s own bars.

p := c.DeMarkSetupPerfected(h, l)
buyClean := c.LT(sup).Sum(9).EQ(0).ValueWhen(k.EQ(-9)).EQ(1)  // no close of the buy setup's nine bars below support
sellClean := c.GT(res).Sum(9).EQ(0).ValueWhen(k.EQ(9)).EQ(1)  // no close of the sell setup's nine bars above resistance
buyOK := p.EQ(-1).Mul(buyClean)  // 1 while the latest completed setup is a perfected buy setup with clean closes
sellOK := p.EQ(1).Mul(sellClean) // 1 while it is a perfected sell setup with clean closes

The support does not change during a buy setup’s nine bars, since no sell setup completes inside it (and the resistance does not change during a sell setup’s), so the sum compares all nine closes with the level that held at the completion. Before the first completed sell setup the support is NaN and no close is below it. Perl’s other conditions, a bar 9 close near the opposite level, the optional close of bar 9 beyond the close of bar 8, and his test of the distance from the bar 9 close to the setup’s own TDST level (the resistance that a completed buy setup has just set, the support that a sell setup has just set; pp. 14 and 17) against the distance to the risk level, are the caller’s.

Setup risk level (Perl, pp. 14 and 17). For a buy setup, take the bar of its nine with the lowest true low and subtract that bar’s true range from its true low; for a sell setup, add the true range of the bar with the highest true high to its true high. Among equal extremes the latest bar is taken. IndexOfLowestS(9) is the position of the latest lowest value in the nine-bar window, 0 for the oldest bar, so 8 minus it is the lag back to that bar:

tl := l.TrueLow(c)
tr := c.TrueRange(h, l, c)
lag := tl.IndexOfLowestS(9).Mul(-1).Add(8) // bars back to the lowest true low of the nine
buyRisk := tl.ShiftVariable(lag).Sub(tr.ShiftVariable(lag)).ValueWhen(k.EQ(-9))
th := h.TrueHigh(c)
lagH := th.IndexOfHighestS(9).Mul(-1).Add(8) // bars back to the highest true high of the nine
sellRisk := th.ShiftVariable(lagH).Add(tr.ShiftVariable(lagH)).ValueWhen(k.EQ(9))

Each level is NaN until the first completed setup of its side and is held until the next. The true range of a bar is its true high minus its true low (h.TrueHigh(c).Sub(l.TrueLow(c)) equals c.TrueRange(h, l, c)). The TDST levels’ NaN rule does not carry over: IndexOfLowestS compares with <=, so a NaN true low on the oldest of the nine bars is kept as the lowest and gives a NaN risk level, while a NaN true low on a later bar is skipped; IndexOfHighestS does the same with >=. If a missing bar should leave the level undefined, test the nine bars at the completion with tl.Lowest(9) (th.Highest(9)), which is NaN for a window that holds a NaN. DeMarkSetupRiskLevel is the method: one series holding the level of the most recently completed setup of either side, NaN when any of its nine bars has a NaN true low or true high. On NaN-free data it equals buyRisk on the bars where k is -9 and sellRisk where k is 9.

TD Sequential’s countdown phase and TD Combo

These methods are the second half of TD Sequential, with TD Aggressive Sequential, TD Combo and the TD risk levels, from Perl’s chapters 1 and 2 with the Bloomberg default settings (pp. 57-58 for TD Sequential, p. 67 for TD Combo):

  • Countdown: 13 bars with a look-back of 2 bars; the termination count and the countdown price are the close; the risk level is taken over all the bars of the countdown; the termination qualifier is on, and the “8 vs 5 Qualifier” (p. 20) and “Show Countdown Bars After Minimum” are off.
  • Recycle: “Reverse Setup Cancel” and “Recycle Confirm” are on; setups within setups are enabled, with “Use Maximum Setup” and “Extreme Setup Closes Within True Range”; the recycle count is 18, the recycle setup rule “Recycle All” and the recycle multiplier 1.000 to 1.618.
  • TD Combo uses the same countdown and recycle settings, and its panel has no termination qualifier. Its option “Use ‘Equal’ for Comparison: All Bars” is a platform option and is not built: the methods follow Perl’s text, whose last two Combo conditions are strict.

The methods:

  • DeMarkCountdown is TD Sequential’s countdown. It starts on the bar that completes a setup, which can be countdown bar 1, and counts a buy bar when the close is at or below the low two bars earlier (a sell bar when the close is at or above the high two bars earlier), not necessarily on consecutive bars. Countdown bar 13 also needs a low at or below the close of countdown bar 8 (a high at or above it); a bar that fails only that test is deferred, Perl’s “+”, and the count stays at 12. The count reads -n on bar n of a buy countdown and +n on bar n of a sell countdown, holds between countdown bars, posts the 13 once and reads 0 when no countdown is developing.
  • DeMarkCountdownAggressive is TD Aggressive Sequential: a buy bar needs a low at or below the low two bars earlier (a sell bar a high at or above the high two bars earlier), with the same bar-8 qualifier.
  • DeMarkCombo is TD Combo in Perl’s strict Version I. It counts from bar 1 of the completed setup, evaluated on the completion bar, which can read up to 9, and a buy bar needs a close at or below the low two bars earlier, a low at or below the previous bar’s low, and a close below both the previous countdown bar’s close (a test skipped on countdown bar 1) and the previous bar’s close (the mirror for a sell). DeMarkComboRelaxed is Version II, whose bars 11 to 13 need only a close below the previous countdown bar’s close (above it for a sell). Neither has a bar-13 qualifier.
  • DeMarkCountdownRiskLevel, DeMarkCountdownAggressiveRiskLevel, DeMarkComboRiskLevel and DeMarkComboRelaxedRiskLevel post the TD risk level of each completed countdown on its 13. Over every bar from countdown bar 1 to bar 13, numbered or not, it is the true low of the bar with the lowest true low less that bar’s true range for a buy, and the true high of the bar with the highest true high plus its true range for a sell, the latest of equal extremes. DeMarkSetupRiskLevel does the same over the nine bars of each completed setup. Each holds its level until the next completion on either side, and a NaN true low or true high in the window makes the level NaN.

One countdown at a time. One countdown develops at a time, on either side. A completed setup of the opposite side cancels it and starts its own countdown, and a true low strictly above the anchor setup’s TDST resistance (a true high strictly below its support) cancels it; a NaN level cancels nothing. When a setup of the same side completes while it develops, the countdown continues if the new setup’s closes lie within the anchor run’s range and its own extreme, the lowest true low for a buy or the highest true high for a sell, does not pass the anchor’s (Qualifier II, tested first); otherwise it restarts on the new setup if the new setup’s range is at least the anchor’s and below 1.618 times it (Qualifier I), and continues if not. A setup run that reaches bar 18 starts a countdown afresh on it, whether or not one is developing (Perl’s R). Bloomberg shows only the countdown closest to completion and lets a second one count in the background (Perl, p. 51); those background countdowns are not modelled. DeMarkCountdown’s doc gives the rulebook in full.

Minimum length. Perl gives at least twenty-two price bars for a TD Sequential signal and only thirteen for TD Combo (p. 59) without saying how he counts them. Counted from the bar before setup bar 1 to countdown bar 13, when countdown bar 1 is setup bar 9, and from setup bar 1 to countdown bar 13 for TD Combo, they match the methods: the earliest 13 falls on bar 25 of a series in DeMarkCountdown and DeMarkCountdownAggressive, and on bar 17 in the two Combos.

Evidence. As for the setup phase, the sources give chart examples only; no backtest supports the countdown signals.

Not built. DeMark’s open-based termination count (p. 26), the validation of a TD Sequential 9-13-9 count (p. 29), the four-step valid break of a risk level (p. 28; Perl prefers an intrabar stop), TD Reference Close (p. 28) and TD Aggressive Combo, which the book names but does not define. The entries are recipes, below.

Countdown recipes

The blocks share their names: c, h and l are the closes, highs and lows, cd and buy13 come from the first block.

Completion and the deferred bars. The 13 is posted once, on its bar. A deferred bar, Perl’s “+”, is a bar on which the count was already 12, still is, and the bar passes the countdown comparison: only the bar-8 qualifier failed. For DeMarkCountdownAggressive the comparisons are l.LTE(l.Shift(2)) and h.GTE(h.Shift(2)).

cd := c.DeMarkCountdown(h, l)
buy13 := cd.EQ(-13) // 1 on the bar where a buy countdown completes
sell13 := cd.EQ(13) // 1 on the bar where a sell countdown completes
buyDeferred := cd.EQ(-12).Mul(cd.StateAge().GT(1)).Mul(c.LTE(l.Shift(2)))
sellDeferred := cd.EQ(12).Mul(cd.StateAge().GT(1)).Mul(c.GTE(h.Shift(2)))

Recycle count 18 (Perl’s R, p. 22). The countdown restarts on the bar where a setup reaches its bar 18. Perl’s chart prints R where the countdown’s 13 would have been; a series cannot rewrite a later bar, so the restart and this flag stand for it.

rBuy := c.DeMarkSetup().EQ(-18)  // 1 where a buy setup reaches bar 18
rSell := c.DeMarkSetup().EQ(18) // 1 where a sell setup reaches bar 18

The risk level of one side. The risk methods hold the level of the latest 13 on either side; the levels of one side are the method sampled on that side’s 13s.

risk := c.DeMarkCountdownRiskLevel(h, l)
buyRisk := risk.ValueWhen(cd.EQ(-13))  // the level of the latest completed buy countdown
sellRisk := risk.ValueWhen(cd.EQ(13)) // the level of the latest completed sell countdown

Entries (Perl, p. 24). The aggressive entry buys on the close of the 13 bar, buy13 itself. The conservative entry waits, after the 13, for the first bullish price flip; the flip on the 13’s own bar does not count, and the next 13 starts the wait again. Any further condition, such as an opposite setup in between, is the caller’s.

up := c.DeMarkPriceFlip().EQ(1).Mul(buy13.EQ(0)) // the bullish flips, less any on a buy 13's own bar
buyEntry := up.Mul(up.SumSince(buy13).EQ(1))     // the first bullish flip after the latest buy 13

Sell entries mirror these with sell13 and the bearish flips, c.DeMarkPriceFlip().EQ(-1).

DeMarkCombo

func (s Series) DeMarkCombo(h, l Series) Series

DeMarkCombo is DeMark’s TD Combo countdown, Perl’s strict Version I, counted from bar 1 of the completed setup and posted from its bar 9 on.

The receiver s holds the closes, written c below, h the highs and l the lows of the same bars. When a countdown is anchored on a setup completing on bar t, afresh or by a recycle, the setup’s bars 1 to 9 (bars t-8 to t) are evaluated in order on that bar and bar t posts the number of them that pass, up to 9; no earlier bar is rewritten (Jason Perl’s DeMark Indicators (2008), p. 60, with the Bloomberg defaults). A completion that leaves a developing countdown in place is tested once, as any other bar. From then on each bar is tested once. A buy countdown counts bar t when c[t] <= l[t-2], l[t] <= l[t-1], c[t] is below the close of the previous countdown bar and c[t] < c[t-1]; a sell countdown when c[t] >= h[t-2], h[t] >= h[t-1], c[t] is above the close of the previous countdown bar and c[t] > c[t-1]. The first two conditions are inclusive and the last two strict, as Perl writes them (pp. 60-61); the comparison with the previous countdown bar is skipped on countdown bar 1. There is no bar-13 qualifier. Bloomberg’s panel option “Use ‘Equal’ for Comparison: All Bars” is a platform option and is not built. The count is held between countdown bars and the 13 is posted once, on its bar; the completed countdowns are cd.EQ(-13) and cd.EQ(13) with cd := c.DeMarkCombo(h, l). One countdown develops at a time, with the cancellations, Qualifier II, Qualifier I and the restart at bar 18 of DeMarkCountdown; a recycle on a completed setup evaluates that setup’s nine bars retrospectively, while a restart at bar 18 counts from that bar on, not retrospectively. Perl’s minimum for a TD Combo signal is 13 bars, setup bar 1 to countdown bar 13, so the earliest 13 falls on bar 17. The setup count is that of DeMarkSetup; the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

NaN, +Inf and -Inf are not errors and are not skipped: a comparison with NaN is false, so a NaN close, high or low fails every test that reads it, a NaN close ends the setup run through it, and +Inf and -Inf compare as ordinary values. The count is not NaN on any input and every 0 is +0. Warm-up: bars 0 to 12 read 0, since no setup completes before bar 13; bar 13 can read up to 9 and bar 17 is the earliest 13. Under a slice of history the count is latched on the setups inside the slice: the slice reads 0 before its first completed setup and agrees with the full history from that bar on when the full history has no countdown developing there after that bar’s cancellations, so give a few hundred bars. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkComboRelaxed

func (s Series) DeMarkComboRelaxed(h, l Series) Series

DeMarkComboRelaxed is the TD Combo countdown in Perl’s less strict Version II, whose bars 11 to 13 need only successively lower (higher) closes.

The receiver s holds the closes, written c below, h the highs and l the lows of the same bars. Countdown bars 1 to 10 are counted as in DeMarkCombo: a completed setup’s bars 1 to 9 are evaluated in order on its completion bar, which posts up to 9 while no earlier bar is rewritten, and each later bar is tested once, a buy bar needing c[t] <= l[t-2], l[t] <= l[t-1], a close below the close of the previous countdown bar and c[t] < c[t-1], a sell bar the mirror, with the comparison with the previous countdown bar skipped on countdown bar 1. Countdown bars 11 to 13 need only a close strictly below the close of the previous countdown bar for a buy, strictly above it for a sell, Perl’s “the closes need only be successively lower”, as in Jason Perl’s DeMark Indicators (2008), pp. 61 and 65, with the Bloomberg defaults. There is no bar-13 qualifier, and Bloomberg’s “Use ‘Equal’ for Comparison: All Bars” is not built. One countdown develops at a time, with the cancellations, Qualifier II, Qualifier I and the restart at bar 18 of DeMarkCountdown (a restart at bar 18 counts from that bar on, not retrospectively), and the 13 is posted once, on its bar: the completed countdowns are cd.EQ(-13) and cd.EQ(13) with cd := c.DeMarkComboRelaxed(h, l). So c.DeMarkCombo(h, l) equals c.DeMarkComboRelaxed(h, l) on every bar before the first 11 of either. The setup count is that of DeMarkSetup; the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

NaN, +Inf and -Inf are not errors and are not skipped: a comparison with NaN is false, so a NaN close, high or low fails every test that reads it, a NaN close ends the setup run through it, and +Inf and -Inf compare as ordinary values. The count is not NaN on any input and every 0 is +0. Warm-up: bars 0 to 12 read 0, since no setup completes before bar 13; bar 13 can read up to 9 and bar 17 is the earliest 13. Under a slice of history the count is latched on the setups inside the slice: the slice reads 0 before its first completed setup and agrees with the full history from that bar on when the full history has no countdown developing there after that bar’s cancellations, so give a few hundred bars. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkComboRelaxedRiskLevel

func (s Series) DeMarkComboRelaxedRiskLevel(h, l Series) Series

DeMarkComboRelaxedRiskLevel is the TD risk level of the most recently completed TD Combo countdown in Version II: the true low of its lowest-true-low bar less that bar’s true range for a buy, the mirror for a sell, held until the next.

The receiver s holds the closes, written c below, h the highs and l the lows of the same bars. The countdown is that of DeMarkComboRelaxed, cd := c.DeMarkComboRelaxed(h, l), run by the same engine under the same rules, those of Jason Perl’s DeMark Indicators (2008) with the Bloomberg defaults (p. 62 and Figure 2.2). When the countdown posts its 13 on bar t, its window is every bar from countdown bar 1 to bar t inclusive, numbered or not; countdown bar 1 can be a bar of the setup, before the completion bar that anchored the countdown, and the window starts there. For a buy countdown the level is tl - (th - tl) on the bar of the window with the lowest true low, the latest of equal lows, where tl is that bar’s true low, the lesser of its low and the close of the bar before, and th its true high, the greater of its high and the close of the bar before; for a sell countdown it is th + (th - tl) on the bar with the highest true high, the latest of equal highs. A NaN true low or true high on any bar of the window makes the level NaN; +Inf and -Inf follow the arithmetic. The level is posted on the 13 bar and held until the next 13 on either side, so with risk := c.DeMarkComboRelaxedRiskLevel(h, l) the result equals risk.ValueWhen(cd.Abs().EQ(13)) on every bar, a NaN matching a NaN, and the buy levels alone are risk.ValueWhen(cd.EQ(-13)). A level posted on a buy 13 that is not NaN is at most that bar’s low, and one posted on a sell 13 at least its high; the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

Warm-up: NaN until the first completed countdown, which cannot fall before bar 17 (NaN rather than 0, since 0 is a price). Under a slice of history the level is NaN before the slice’s first 13 and equals the full history’s from the first 13 at or after the bar from which the counts agree, the slice’s first completed setup when the full history has no countdown developing there after that bar’s cancellations: the setups inside the slice decide, so give a few hundred bars. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkComboRiskLevel

func (s Series) DeMarkComboRiskLevel(h, l Series) Series

DeMarkComboRiskLevel is the TD risk level of the most recently completed TD Combo countdown in Version I: the true low of its lowest-true-low bar less that bar’s true range for a buy, the mirror for a sell, held until the next.

The receiver s holds the closes, written c below, h the highs and l the lows of the same bars. The countdown is that of DeMarkCombo, cd := c.DeMarkCombo(h, l), run by the same engine under the same rules, those of Jason Perl’s DeMark Indicators (2008) with the Bloomberg defaults (p. 62 and Figure 2.2). When the countdown posts its 13 on bar t, its window is every bar from countdown bar 1 to bar t inclusive, numbered or not; countdown bar 1 can be a bar of the setup, before the completion bar that anchored the countdown, and the window starts there. For a buy countdown the level is tl - (th - tl) on the bar of the window with the lowest true low, the latest of equal lows, where tl is that bar’s true low, the lesser of its low and the close of the bar before, and th its true high, the greater of its high and the close of the bar before; for a sell countdown it is th + (th - tl) on the bar with the highest true high, the latest of equal highs. A NaN true low or true high on any bar of the window makes the level NaN; +Inf and -Inf follow the arithmetic. The level is posted on the 13 bar and held until the next 13 on either side, so with risk := c.DeMarkComboRiskLevel(h, l) the result equals risk.ValueWhen(cd.Abs().EQ(13)) on every bar, a NaN matching a NaN, and the buy levels alone are risk.ValueWhen(cd.EQ(-13)). A level posted on a buy 13 that is not NaN is at most that bar’s low, and one posted on a sell 13 at least its high; the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

Warm-up: NaN until the first completed countdown, which cannot fall before bar 17 (NaN rather than 0, since 0 is a price). Under a slice of history the level is NaN before the slice’s first 13 and equals the full history’s from the first 13 at or after the bar from which the counts agree, the slice’s first completed setup when the full history has no countdown developing there after that bar’s cancellations: the setups inside the slice decide, so give a few hundred bars. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkCountdown

func (s Series) DeMarkCountdown(h, l Series) Series

DeMarkCountdown is DeMark’s TD Sequential countdown on the receiver’s closes: -k on bar k of a buy countdown, +k on bar k of a sell countdown, held between countdown bars and 0 when none is developing.

The receiver s holds the closes, h the highs and l the lows of the same bars; below, the closes are written c, the caller’s view, as in cd := c.DeMarkCountdown(h, l). The rules are those of Jason Perl’s DeMark Indicators (2008) with the Bloomberg default settings, run on the setup count of DeMarkSetup; the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

A countdown starts on the bar that completes a setup, bar 9 of a setup run, and that bar can be countdown bar 1: a buy countdown counts bar t when c[t] <= l[t-2] and a sell countdown when c[t] >= h[t-2], both inclusive (Perl, p. 18). Until a bar passes, bar 1 is postponed and the count reads 0. Countdown bars need not be consecutive: a bar that fails leaves the count where it is, so every bar of a developing countdown reads its latest count. On the bar that would be countdown bar 13 the termination qualifier (on by default, p. 19) also requires a low at or below the close of countdown bar 8 for a buy, a high at or above it for a sell; a bar that passes the comparison but fails the qualifier is a deferred bar, Perl’s “+”, on which the count stays at 12 and the following bars are tested again. The deferred buy bars are cd.EQ(-12).Mul(cd.StateAge().GT(1)).Mul(c.LTE(l.Shift(2))) and the deferred sell bars the mirror with cd.EQ(12) and c.GTE(h.Shift(2)). The 13 is posted once, on its bar: the next bar reads 0 unless a countdown is anchored there, so the completed buy countdowns are cd.EQ(-13) and the completed sell countdowns cd.EQ(13).

One countdown develops at a time, on either side (Perl, p. 21). It is cancelled when a setup of the opposite side completes, which starts a countdown of that side on the same bar, or when the bar’s true low rises strictly above the anchor setup’s TDST resistance for a buy (the highest TrueHigh of the setup’s bars 1 to 9, the value DeMarkSetupResistance posted on its bar 9) or its true high falls strictly below the TDST support for a sell (the lowest TrueLow of its bars 1 to 9, the value of DeMarkSetupSupport). The level is the anchor setup’s own and does not move with a later setup that leaves the countdown in place. A NaN level cancels nothing, and nor does a NaN true low or true high. After a cancellation the next completed setup, or bar 18 of a run, starts a countdown.

When a setup of the same side completes while a countdown develops, Qualifier II is tested first: the new setup is contained, and the countdown continues as it is, when every close of the new setup’s bars 1 to 9 lies within the anchor run’s extremes (its lowest true low to its highest true high over the anchor run’s whole extension, bars beyond 9 included for as long as the run lasted) and, for a buy, its lowest true low is at or above the anchor’s, for a sell its highest true high at or below the anchor’s, every comparison inclusive (pp. 21-22). Otherwise Qualifier I compares the ranges: with oldR the anchor run’s range and newR the new setup’s range over its bars 1 to 9, the countdown is recycled, restarting on the new setup, when oldR <= newR and newR is below 1.618 times oldR; outside that band the countdown continues as it is. A NaN range recycles nothing. A recycle on the bar where the old countdown would have posted its 13 discards that 13. When a setup run reaches bar 18 (Perl’s R, p. 22) the countdown restarts on that run, whatever was developing and whether anything was, with the level of the run’s bars 1 to 9; those bars are c.DeMarkSetup().EQ(-18) and c.DeMarkSetup().EQ(18).

Bloomberg’s background countdowns (so there is no “closest to completion” rule), the open-based termination count, the 8 versus 5 qualifier, “Include Prior Four Bars” and “Show Countdown Bars After Minimum” are not built: the background countdowns have no stated start rule, and the rest are off by default or are not Perl’s preference.

NaN, +Inf and -Inf are not errors and are not skipped: a comparison with NaN is false, so a NaN close, high or low fails every test that reads it, a NaN close ends the setup run through it, and +Inf and -Inf compare as ordinary values. The count is not NaN on any input and every 0 is +0. Warm-up: bars 0 to 12 read 0, since no setup completes before bar 13, and the earliest 13 falls on bar 25. Under a slice of history the count is latched on the setups inside the slice: the slice reads 0 before its first completed setup and agrees with the full history from that bar on when the full history has no countdown developing there after that bar’s cancellations, so give a few hundred bars. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkCountdownAggressive

func (s Series) DeMarkCountdownAggressive(h, l Series) Series

DeMarkCountdownAggressive is the TD Aggressive Sequential countdown, which counts a buy bar on a low at or below the low two bars earlier and a sell bar on a high at or above the high two bars earlier.

The receiver s holds the closes, written c below, h the highs and l the lows of the same bars. A buy countdown counts bar t when l[t] <= l[t-2] and a sell countdown when h[t] >= h[t-2], both inclusive, in place of the close comparisons of DeMarkCountdown (Jason Perl’s DeMark Indicators (2008), p. 58, with the Bloomberg defaults). Everything else is as in DeMarkCountdown: the start on the completion bar of a setup, with a postponed bar 1 until a bar passes; the count held between countdown bars; one countdown at a time, cancelled by an opposite completion or a strict break of the anchor setup’s own TDST level, where a NaN level cancels nothing; Qualifier II before Qualifier I, with the band from the anchor’s range to 1.618 times it; the restart at bar 18; the 13 posted once; and the termination qualifier, which is unchanged: countdown bar 13 also needs a low at or below the close of countdown bar 8 for a buy, a high at or above it for a sell, and a bar that passes the comparison but not the qualifier is deferred, with the count staying at 12. The deferred buy bars are cd.EQ(-12).Mul(cd.StateAge().GT(1)).Mul(l.LTE(l.Shift(2))) and the deferred sell bars the mirror with cd.EQ(12) and h.GTE(h.Shift(2)), with cd := c.DeMarkCountdownAggressive(h, l); the completed countdowns are cd.EQ(-13) and cd.EQ(13). The setup count is that of DeMarkSetup; the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

On bars with l <= c <= h and no NaN, a bar that passes the close comparison of DeMarkCountdown passes this one, so the absolute count here is at least that of DeMarkCountdown on every bar before the first 13 of either. From then on the two can differ either way: a TD Sequential 13 can be posted while this countdown is deferred at 12 by the bar-8 qualifier, which qualifies Perl’s remark that TD Aggressive Sequential signals first.

NaN, +Inf and -Inf are not errors and are not skipped: a comparison with NaN is false, so a NaN high or low fails every test that reads it, a NaN close ends the setup run through it (and fails the bar-8 qualifier when it is the close of countdown bar 8), and +Inf and -Inf compare as ordinary values. The count is not NaN on any input and every 0 is +0. Warm-up: bars 0 to 12 read 0, since no setup completes before bar 13, and the earliest 13 falls on bar 25. Under a slice of history the count is latched on the setups inside the slice: the slice reads 0 before its first completed setup and agrees with the full history from that bar on when the full history has no countdown developing there after that bar’s cancellations, so give a few hundred bars. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkCountdownAggressiveRiskLevel

func (s Series) DeMarkCountdownAggressiveRiskLevel(h, l Series) Series

DeMarkCountdownAggressiveRiskLevel is the TD risk level of the most recently completed TD Aggressive Sequential countdown: the true low of its lowest-true-low bar less that bar’s true range for a buy, the mirror for a sell, held until the next.

The receiver s holds the closes, written c below, h the highs and l the lows of the same bars. The countdown is that of DeMarkCountdownAggressive, cd := c.DeMarkCountdownAggressive(h, l), run by the same engine under the same rules, those of Jason Perl’s DeMark Indicators (2008) with the Bloomberg defaults; the window and the formulas are those of the TD Sequential level (p. 26 and Figure 1.20), applied to the aggressive countdown. When the countdown posts its 13 on bar t, its window is every bar from countdown bar 1 to bar t inclusive, numbered or not. For a buy countdown the level is tl - (th - tl) on the bar of the window with the lowest true low, the latest of equal lows, where tl is that bar’s true low, the lesser of its low and the close of the bar before, and th its true high, the greater of its high and the close of the bar before; for a sell countdown it is th + (th - tl) on the bar with the highest true high, the latest of equal highs. A NaN true low or true high on any bar of the window makes the level NaN; +Inf and -Inf follow the arithmetic. The level is posted on the 13 bar and held until the next 13 on either side, so with risk := c.DeMarkCountdownAggressiveRiskLevel(h, l) the result equals risk.ValueWhen(cd.Abs().EQ(13)) on every bar, a NaN matching a NaN, and the buy levels alone are risk.ValueWhen(cd.EQ(-13)). A level posted on a buy 13 that is not NaN is at most that bar’s low, and one posted on a sell 13 at least its high; the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

Warm-up: NaN until the first completed countdown, which cannot fall before bar 25 (NaN rather than 0, since 0 is a price). Under a slice of history the level is NaN before the slice’s first 13 and equals the full history’s from the first 13 at or after the bar from which the counts agree, the slice’s first completed setup when the full history has no countdown developing there after that bar’s cancellations: the setups inside the slice decide, so give a few hundred bars. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkCountdownRiskLevel

func (s Series) DeMarkCountdownRiskLevel(h, l Series) Series

DeMarkCountdownRiskLevel is the TD risk level of the most recently completed TD Sequential countdown: the true low of its lowest-true-low bar less that bar’s true range for a buy, the mirror for a sell, held until the next.

The receiver s holds the closes, written c below, h the highs and l the lows of the same bars. The countdown is that of DeMarkCountdown, cd := c.DeMarkCountdown(h, l), run by the same engine under the same rules, those of Jason Perl’s DeMark Indicators (2008) with the Bloomberg defaults (p. 26 and Figure 1.20). When the countdown posts its 13 on bar t, its window is every bar from countdown bar 1 to bar t inclusive, numbered or not. For a buy countdown the level is tl - (th - tl) on the bar of the window with the lowest true low, the latest of equal lows, where tl is that bar’s true low, the lesser of its low and the close of the bar before, and th its true high, the greater of its high and the close of the bar before; for a sell countdown it is th + (th - tl) on the bar with the highest true high, the latest of equal highs. A NaN true low or true high on any bar of the window makes the level NaN; +Inf and -Inf follow the arithmetic. The level is posted on the 13 bar and held until the next 13 on either side, so with risk := c.DeMarkCountdownRiskLevel(h, l) the result equals risk.ValueWhen(cd.Abs().EQ(13)) on every bar, a NaN matching a NaN, and the buy levels alone are risk.ValueWhen(cd.EQ(-13)). A level posted on a buy 13 that is not NaN is at most that bar’s low, and one posted on a sell 13 at least its high; the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

Warm-up: NaN until the first completed countdown, which cannot fall before bar 25 (NaN rather than 0, since 0 is a price). Under a slice of history the level is NaN before the slice’s first 13 and equals the full history’s from the first 13 at or after the bar from which the counts agree, the slice’s first completed setup when the full history has no countdown developing there after that bar’s cancellations: the setups inside the slice decide, so give a few hundred bars. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkPriceFlip

func (s Series) DeMarkPriceFlip() Series

DeMarkPriceFlip marks DeMark’s TD Price Flip on the receiver’s closes: +1 on a bullish flip, -1 on a bearish flip and 0 otherwise.

With c the closes, a bearish flip on bar t is c[t-1] > c[t-5] and c[t] < c[t-4]: a close above the close four bars earlier, immediately followed by a close below the close four bars earlier (Perl, p. 2). A bullish flip is the mirror, c[t-1] < c[t-5] and c[t] > c[t-4]. The comparisons are strict float64 comparisons: a tie, -0 against +0 included, gives no flip, a comparison with NaN is false, and the infinities are ordinary values. The output is -1, 0 or +1 on every bar and is not NaN on any input; a zero is +0.

The flip does not depend on any setup state. A bearish flip is bar 1 of a buy setup and a bullish flip is bar 1 of a sell setup, so the flip equals c.DeMarkSetup() exactly where the count is -1 or +1, and a flip against a running setup ends it: a bearish flip during a sell setup starts a buy setup on the same bar. With up := c.GT(c.Shift(4)) and dn := c.LT(c.Shift(4)), the result equals up.Mul(dn.Shift(1)).Sub(dn.Mul(up.Shift(1))).SetN(5, 0) bit for bit on every bar, and so does k.Abs().EQ(1).Mul(k).Add(0) for k := c.DeMarkSetup().

Warm-up: bars 0 to 4 read 0, since a flip needs bar t-5, and bar 5 is the first that can read -1 or +1. The flip on bar t reads bars t-5 to t only, so where a slice of history starts matters only for the slice’s first five bars: for d := c[m:], d.DeMarkPriceFlip() equals c.DeMarkPriceFlip()[m:] from bar 5 of the slice on, and bars 0 to 4 inside the slice read 0. An empty receiver gives an empty, non-nil Series.

The rules are those of Jason Perl’s DeMark Indicators (2008), with the Bloomberg default settings. See the manual’s “DeMark Indicators” section for the trademark attribution, the recipes and the absence of any backtest. Pure: the result is a new Series, the receiver is not modified, concurrent calls are safe, and the method allocates only the result.

DeMarkSetup

func (s Series) DeMarkSetup() Series

DeMarkSetup is DeMark’s TD Setup count on the receiver’s closes: -k on bar k of a buy setup, +k on bar k of a sell setup and 0 otherwise, counting past 9 until the run ends.

With c the closes, a buy setup starts on a bearish flip, c[t-1] > c[t-5] and c[t] < c[t-4] (see DeMarkPriceFlip), which is its bar 1 and reads -1, and continues while each close is strictly below the close four bars earlier, c[t] < c[t-4], reading -2, -3 and so on. A sell setup mirrors it: it starts on a bullish flip as +1 and continues while c[t] > c[t-4]. Any bar without the run’s comparison ends the run, whatever its length: a close equal to the close four bars earlier (-0 against +0 included), a comparison with NaN, or a close on the other side. That last close is itself a flip of the opposite sign and so bar 1 of the other setup, while a tie or a NaN comparison gives 0. From bar to bar the size of the count rises by exactly 1 or falls to 0 or 1, and the count is -1 or +1 exactly where DeMarkPriceFlip is -1 or +1.

A run of lower (higher) closes that begins without a flip, because the prior-bar comparison of its first bar tied, read a NaN or came before bar 5, reads 0 throughout, so a series rising from bar 0 reads 0 everywhere. The count does not stop at 9: it continues as long as the run persists (Perl, p. 23), and c.DeMarkSetup().Clamp(-9, 9) gives the display of charting systems, which show bars 1 to 9 only. A buy setup completes on its bar 9, where c.DeMarkSetup().EQ(-9) is 1, and a sell setup where c.DeMarkSetup().EQ(9) is 1; each setup completes once, and bar 13 is the first bar that can complete one (a flip on bar 5, and its bar 9 on bar 13).

The count is the age of a run whose first bar is a flip. With x := c.LT(c.Shift(4)).SetN(4, 0), a := x.StateAge(), g := c.Shift(1).GT(c.Shift(5)).SetN(5, 0).ValueWhen(a.EQ(1)) and buy := a.Mul(x).Mul(g), and their mirrors y := c.GT(c.Shift(4)).SetN(4, 0), b := y.StateAge(), gs := c.Shift(1).LT(c.Shift(5)).SetN(5, 0).ValueWhen(b.EQ(1)) and sell := b.Mul(y).Mul(gs), the result equals sell.Sub(buy) bit for bit on every bar, NaN, the infinities, signed zeros and ties included. Coles’s MetaStock test for a completed buy setup (2011) is, in this notation, x.Sum(9).EQ(9).Mul(c.Shift(9).GT(c.Shift(13))), and it equals c.DeMarkSetup().EQ(-9) from bar 13 on; its sell form, y.Sum(9).EQ(9).Mul(c.Shift(9).LT(c.Shift(13))), equals c.DeMarkSetup().EQ(9) from bar 13 on (before bar 13 the Shift padding can fire them). His printed listing maps price field 4, labelled C, to the low, a misprint. pandas-ta’s td_seq is a different count: it counts runs of strict c[t] < c[t-4] (and of c[t] > c[t-4]) with no flip and caps them at 13, so it also counts runs that this method reads as 0; on a buy run that began with a flip it equals the negated count while the run is at most 13 bars long.

A NaN close on bar p makes both comparisons false on bars p and p+4, and the prior-bar comparisons of the flips on bars p+1 and p+5 false; the infinities are ordinary values. The count is a whole number stored as float64, a zero is +0, and the output is not NaN on any input. Warm-up: bars 0 to 4 read 0 (the real no-setup state), bar 5 is the first that can read -1 or +1, and bar 13 the first that can complete a setup. Under a slice of history the count settles at the first flip inside the slice: for d := c[m:], d.DeMarkSetup() reads 0 before the first non-zero of d.DeMarkPriceFlip() and equals c.DeMarkSetup()[m:] from that bar on, so give a few hundred bars. An empty receiver gives an empty, non-nil Series.

DeMarkSetupPerfected, DeMarkSetupResistance and DeMarkSetupSupport read this count, and each runs it again, as do the countdowns and the TD risk levels of the manual’s “DeMark Indicators” section. The rules are those of Jason Perl’s DeMark Indicators (2008), with the Bloomberg default settings: a minimum of 9 bars, a look-back of 4 and the close as the setup price. See the manual’s “DeMark Indicators” section for the trademark attribution, the recipes and the absence of any backtest. Pure: the result is a new Series, the receiver is not modified, and the method allocates only the result.

DeMarkSetupPerfected

func (s Series) DeMarkSetupPerfected(h, l Series) Series

DeMarkSetupPerfected reports whether the most recently completed TD Setup is perfected: -1 for a buy, +1 for a sell, 0 while deferred or before the first completion.

The receiver is the closes c, h the highs and l the lows, and the setup count is c.DeMarkSetup(). When a buy setup completes on bar t (the count is -9, its bar 9), the reference is r = min(l[t-3], l[t-2]), the lesser of the lows of setup bars 6 and 7, and the setup is perfected on its bar 9 if l[t-1] <= r or l[t] <= r, the low of bar 8 or of bar 9 at or below it: the output becomes -1. Otherwise perfection is deferred: the output reads 0 and the first later bar with l[t] <= r perfects the setup. A sell setup mirrors this with the highs: r = max(h[t-3], h[t-2]), and h[t-1] >= r or h[t] >= r, or a later h[t] >= r, gives +1. Perl’s rule box (p. 11) asks for a low of bar 8 or 9, or a subsequent low, “less than, or equal to,” the lows of bars 6 and 7, so equal lows perfect: <= for buys and >= for sells.

The output belongs to the most recently completed setup on either side. Each completion replaces whatever was held or pending, even on a bar whose low (high) would satisfy the pending reference, and a setup deferred on its bar 9 reads 0 there even when the previous setup’s -1 or +1 was held; between completions the value is held. A deferral has no other expiry: a flip, a setup that starts but does not complete, or any number of bars leaves it pending until a later low (high) perfects it or the next completion on either side replaces it. Perl gives no limit, and his Figure 1.10 perfects a buy setup five bars after its bar 9.

A comparison with NaN is false. A NaN low on bar 6 or 7 makes r NaN, so that buy setup cannot be perfected; a NaN low on bar 8 leaves the test to bar 9 and a NaN low on bar 9 leaves it to bar 8, since the two bars are tested one by one; a NaN low on a later bar does not perfect it. Sells mirror this with the highs. The infinities are ordinary values, so a -Inf low on bar 6 is matched only by a -Inf low. A NaN close affects the count only. The output is -1, 0 or +1 on every bar and is not NaN on any input.

The perfecting bars are p.Mul(p.StateAge().EQ(1)) with p the output: non-zero exactly where p changes to -1 or +1, on or after bar 9 of a completed setup and before the next completion, with the sign of its side and at most one for each completed setup (none when a setup is perfected on its bar 9 while the previous setup’s equal value is held). Perfection is Perl’s first condition for trading a completed setup.

If h or l does not have the receiver’s length, the result is Series{}. Warm-up: 0 before the first completion, so bars 0 to 12 read 0. Under a slice d := c[m:] (h and l sliced alike) the output reads 0 before the first completed setup inside the slice and equals the full result from it on. An empty receiver gives an empty, non-nil Series.

The rules are those of Jason Perl’s DeMark Indicators (2008), with the Bloomberg default settings. See the manual’s “DeMark Indicators” section for the trademark attribution, the recipes and the absence of any backtest. Pure: the result is a new Series, no input is modified, even when h or l is the receiver, and the method allocates only the result.

DeMarkSetupResistance

func (s Series) DeMarkSetupResistance(h Series) Series

DeMarkSetupResistance is the TDST resistance level, the highest true high of bars 1 to 9 of the most recently completed buy setup, held until the next.

The receiver is the closes c and h the highs. When a buy setup completes on bar t, its bar 9, where c.DeMarkSetup() is -9, the level becomes the greatest TrueHigh of the setup’s bars 1 to 9, that is bars t-8 to t, where the true high of bar j is max(h[j], c[j-1]). The true high reaches back to the close before a bar that gapped down, so the level can be a close rather than a high. The level is held on every later bar until the next completed buy setup replaces it: it is held through sell setups and through the bars beyond 9 of the same run, which are ignored. Perl, p. 14: TDST resistance is “the true high of the most recently completed TD Buy Setup”. Bloomberg’s setup option “Include Prior Four Bars” and its TDST options “Extend the 2nd Most Recent TDST Level” and “Open Restriction”, all off by default, are not built.

The nine true highs are folded with Go’s builtin max: a NaN true high among them gives a NaN level until the next completed buy setup, even beside +Inf; +0 is taken over -0; and the infinities are otherwise ordinary values. The result equals h.TrueHigh(c).Highest(9).ValueWhen(c.DeMarkSetup().EQ(-9)) bit for bit on every bar, for equal-length inputs of any values.

Perl reads the level in two scenarios: a sell setup none of whose closes is above TDST resistance lacks the momentum to break out of the range, so a reversal or at least a consolidation is expected, while a close above it suggests that the uptrend continues; TDST support plays the same part for buy setups. With res := c.DeMarkSetupResistance(h) and sup := c.DeMarkSetupSupport(l), the trend bias c.GT(res).Sub(c.LT(sup)) is +1 on a close above resistance, -1 on a close below support and 0 otherwise (a comparison with a NaN level is false).

If h does not have the receiver’s length, the result is Series{}. An empty receiver gives an empty, non-nil Series. Warm-up: NaN until the first completed buy setup, NaN rather than 0 since the start depends on the data, so bars 0 to 12 read NaN. Under a slice d := c[m:] (h sliced alike) the level reads NaN before the first completed buy setup inside the slice and equals the full result from it on.

The rules are those of Jason Perl’s DeMark Indicators (2008), with the Bloomberg default settings. See the manual’s “DeMark Indicators” section for the trademark attribution, the recipes and the absence of any backtest. Pure: the result is a new Series, no input is modified, even when h is the receiver, and the method allocates only the result.

DeMarkSetupRiskLevel

func (s Series) DeMarkSetupRiskLevel(h, l Series) Series

DeMarkSetupRiskLevel is the TD risk level of the most recently completed TD Setup, from the extreme true low or true high of its bars 1 to 9, held until the next completion.

The receiver s holds the closes, written c below, h the highs and l the lows of the same bars; the setup count is that of DeMarkSetup, and no countdown is run. When a buy setup completes on bar t, where that count reads -9, the level is tl - (th - tl) on the bar of bars t-8 to t with the lowest true low, the latest of equal lows, where tl is that bar’s true low, the lesser of its low and the close of the bar before, and th its true high, the greater of its high and the close of the bar before; when a sell setup completes (the count reads 9) it is th + (th - tl) on the bar with the highest true high, the latest of equal highs. These are Perl’s stops for trading a completed setup, as in Jason Perl’s DeMark Indicators (2008), pp. 14 and 17, with the Bloomberg defaults. A NaN true low or true high on any of the nine bars makes the level NaN; +Inf and -Inf follow the arithmetic. The level is posted on the completion bar and held until the next completion on either side; the bars of a setup beyond 9 do not move it, so with k := c.DeMarkSetup() the result equals its own ValueWhen(k.Abs().EQ(9)) on every bar. On NaN-free data the level on a buy completion bar equals tl.ShiftVariable(lag).Sub(tr.ShiftVariable(lag)) with tl := l.TrueLow(c), tr := c.TrueRange(h, l, c) and lag := tl.IndexOfLowestS(9).Mul(-1).Add(8), and on a sell completion bar th.ShiftVariable(lagH).Add(tr.ShiftVariable(lagH)) with th := h.TrueHigh(c) and lagH := th.IndexOfHighestS(9).Mul(-1).Add(8); that ShiftVariable recipe can differ on NaN data, and the manual’s “DeMark Indicators” section holds the trademark attribution, the recipes and the note that nothing here is a backtest.

Warm-up: NaN until the first completed setup, which cannot fall before bar 13 (NaN rather than 0, since 0 is a price). Under a slice of history the level is NaN before the slice’s first completed setup and equals the full history’s from that bar on: the setups inside the slice decide. Pure: the inputs are not modified, even when the receiver and the arguments are one slice, and the result is a new Series. The result is Series{} when len(h) or len(l) differs from len(s), and an empty Series for an empty receiver.

DeMarkSetupSupport

func (s Series) DeMarkSetupSupport(l Series) Series

DeMarkSetupSupport is the TDST support level, the lowest true low of bars 1 to 9 of the most recently completed sell setup, held until the next.

The receiver is the closes c and l the lows. When a sell setup completes on bar t, its bar 9, where c.DeMarkSetup() is 9, the level becomes the least TrueLow of the setup’s bars 1 to 9, that is bars t-8 to t, where the true low of bar j is min(l[j], c[j-1]). The true low reaches back to the close before a bar that gapped up, so the level can be a close rather than a low. The level is held on every later bar until the next completed sell setup replaces it: it is held through buy setups and through the bars beyond 9 of the same run, which are ignored. Perl, p. 17: TDST support is “the true low of the most recently completed TD Sell Setup”. Bloomberg’s setup option “Include Prior Four Bars” and its TDST options “Extend the 2nd Most Recent TDST Level” and “Open Restriction”, all off by default, are not built.

The nine true lows are folded with Go’s builtin min: a NaN true low among them gives a NaN level until the next completed sell setup, even beside -Inf; -0 is taken over +0; and the infinities are otherwise ordinary values. The result equals l.TrueLow(c).Lowest(9).ValueWhen(c.DeMarkSetup().EQ(9)) bit for bit on every bar, for equal-length inputs of any values.

Perl reads the level in two scenarios: a buy setup none of whose closes is below TDST support lacks the momentum to break out of the range, so a reversal or at least a consolidation is expected, while a close below it suggests that the downtrend continues; TDST resistance plays the same part for sell setups. With res := c.DeMarkSetupResistance(h) and sup := c.DeMarkSetupSupport(l), the trend bias c.GT(res).Sub(c.LT(sup)) is +1 on a close above resistance, -1 on a close below support and 0 otherwise (a comparison with a NaN level is false).

If l does not have the receiver’s length, the result is Series{}. An empty receiver gives an empty, non-nil Series. Warm-up: NaN until the first completed sell setup, NaN rather than 0 since the start depends on the data, so bars 0 to 12 read NaN. Under a slice d := c[m:] (l sliced alike) the level reads NaN before the first completed sell setup inside the slice and equals the full result from it on.

The rules are those of Jason Perl’s DeMark Indicators (2008), with the Bloomberg default settings. See the manual’s “DeMark Indicators” section for the trademark attribution, the recipes and the absence of any backtest. Pure: the result is a new Series, no input is modified, even when l is the receiver, and the method allocates only the result.