up = up ?not (close < finalLower) : close > finalUpper line = up ? finalLower : finalUpper
Appends two columns:
${prefix} — the line (st at the default prefix).
${prefix}Trend — +1 while the line is below price, −1 above.
Two columns, not four — the bands are intermediates
The obvious fourth and fifth columns are ${prefix}Upper / ${prefix}Lower
(the two final bands), and they are deliberately not shipped. The line
already is whichever band is live — ${prefix} equals the final lower
band exactly when ${prefix}Trend is +1 and the final upper band exactly
when it is −1 — so the drawn band is always present and the extra columns
would only ever expose the inactive one, which no published SuperTrend
chart draws and no consumer has asked for. Publishing it would also make
the study's contract wider than its definition: the inactive band's value
is an artefact of the ratchet's bookkeeping, and pinning it in the schema
would freeze an implementation detail. If a consumer turns up who needs
both bands, that is a two-column addition to this file, not a redesign
(see the plan write-up).
The naming follows parabolicSar: the bare ${prefix} is the
principal value and ${prefix}Trend annotates it. The same sign convention
holds across both — +1 means the stop/line sits below price.
Which SuperTrend
Seban's definition as implemented by TradingView's ta.supertrend,
which is what a caller's chart draws and what the ChartIQ / Investing.com /
TradingView family agree on. TA-Lib has no SuperTrend, so the oracle is a
pandas replication with the ratchet spelled out term by term, and a case
separating it from the two nearby readings that are easy to write by
accident (ratcheting against this bar's close instead of the previous
one, and flipping on the previous final band instead of the ratcheted
one).
Two conventions worth naming because implementations differ on them:
The ATR is Wilder's (atrValues — true range, Wilder-smoothed,
the same array atr and keltner read), not an SMA of true
range. TradingView's ta.atr is also Wilder's.
The seed side is down. On the first bar with a finite ATR both bands
take their basic values and the line starts on the upper band, i.e.
${prefix}Trend = −1. This mirrors ta.supertrend's direction := 1
branch (its 1 is a downtrend). The side is corrected by the data at the
first close through a band and is not sticky, but it does mean the first
few bars of a series that opens in an uptrend read −1.
The trend sign is inverted relative to Pine.ta.supertrend returns
-1 for an uptrend; this study returns +1, matching
parabolicSar and the plain reading of "trend".
Warm-up and gaps
Length-preserving. Both columns start on the ATR's first bar — bar period
on gap-free input, since atrValues skips the first bar's undefined true
range and then needs period values. The bands are seeded there rather
than being masked further back.
The ATR is the study's gap rule in practice. A missing high, low or
close makes the true range NaN on that bar and the next, and Wilder's
recursion then propagates to the end — so the whole study reads
undefined from an interior hole onwards, which is atr's documented
behaviour rather than anything this study adds. The K6 reset rule
([PND-SFOLD], kernels/fold.ts) is therefore invisible here except for a
gap that lands only in a column the ATR does not read, which for
SuperTrend is none of them. A caller who needs continuity across interior
gaps fills before smoothing.
Edges
In the units of the price: scaling every bar by k scales the line
by k and leaves the trend column unchanged; adding c shifts it by
c. It does not normalise.
A flat stretch gives ATR = 0, a zero-width band, and a line sitting
exactly on (high+low)/2. There is no division anywhere in the rule, so
there is no zero-denominator case (the keltner precedent).
A one-bar series, or one shorter than period + 1, gives two
all-undefined columns rather than throwing.
SuperTrend (Olivier Seban) — an ATR band that ratchets towards price and flips side when price closes through it. Kernel K6 over atrValues.
Appends two columns:
${prefix}— the line (stat the default prefix).${prefix}Trend—+1while the line is below price,−1above.Two columns, not four — the bands are intermediates
The obvious fourth and fifth columns are
${prefix}Upper/${prefix}Lower(the two final bands), and they are deliberately not shipped. The line already is whichever band is live —${prefix}equals the final lower band exactly when${prefix}Trendis+1and the final upper band exactly when it is−1— so the drawn band is always present and the extra columns would only ever expose the inactive one, which no published SuperTrend chart draws and no consumer has asked for. Publishing it would also make the study's contract wider than its definition: the inactive band's value is an artefact of the ratchet's bookkeeping, and pinning it in the schema would freeze an implementation detail. If a consumer turns up who needs both bands, that is a two-column addition to this file, not a redesign (see the plan write-up).The naming follows parabolicSar: the bare
${prefix}is the principal value and${prefix}Trendannotates it. The same sign convention holds across both —+1means the stop/line sits below price.Which SuperTrend
Seban's definition as implemented by TradingView's
ta.supertrend, which is what a caller's chart draws and what the ChartIQ / Investing.com / TradingView family agree on. TA-Lib has no SuperTrend, so the oracle is a pandas replication with the ratchet spelled out term by term, and a case separating it from the two nearby readings that are easy to write by accident (ratcheting against this bar's close instead of the previous one, and flipping on the previous final band instead of the ratcheted one).Two conventions worth naming because implementations differ on them:
ta.atris also Wilder's.${prefix}Trend = −1. This mirrorsta.supertrend'sdirection := 1branch (its1is a downtrend). The side is corrected by the data at the first close through a band and is not sticky, but it does mean the first few bars of a series that opens in an uptrend read−1.ta.supertrendreturns-1for an uptrend; this study returns+1, matching parabolicSar and the plain reading of "trend".Warm-up and gaps
Length-preserving. Both columns start on the ATR's first bar — bar
periodon gap-free input, sinceatrValuesskips the first bar's undefined true range and then needsperiodvalues. The bands are seeded there rather than being masked further back.The ATR is the study's gap rule in practice. A missing
high,loworclosemakes the true rangeNaNon that bar and the next, and Wilder's recursion then propagates to the end — so the whole study readsundefinedfrom an interior hole onwards, which isatr's documented behaviour rather than anything this study adds. The K6 reset rule ([PND-SFOLD],kernels/fold.ts) is therefore invisible here except for a gap that lands only in a column the ATR does not read, which for SuperTrend is none of them. A caller who needs continuity across interior gaps fills before smoothing.Edges
kscales the line bykand leaves the trend column unchanged; addingcshifts it byc. It does not normalise.ATR = 0, a zero-width band, and a line sitting exactly on(high+low)/2. There is no division anywhere in the rule, so there is no zero-denominator case (the keltner precedent).period + 1, gives two all-undefinedcolumns rather than throwing.