DSL Technical Analysis API¶
The ta.* namespace contains common technical analysis helpers.
Moving Averages¶
ta.sma¶
ma = ta.sma(close, length)
Simple moving average.
ta.ema¶
ema = ta.ema(close, length)
Exponential moving average.
ta.rma¶
rma = ta.rma(close, length)
Wilder moving average.
Rolling Window¶
ta.sum¶
sum = ta.sum(volume, length)
Rolling sum.
ta.highest¶
highestHigh = ta.highest(high, length)
Highest value in a rolling window.
ta.lowest¶
lowestLow = ta.lowest(low, length)
Lowest value in a rolling window.
ta.stdev¶
dev = ta.stdev(close, length)
Rolling standard deviation.
Bollinger Bands¶
ta.bb_basis¶
basis = ta.bb_basis(close, length)
Bollinger basis.
ta.bb_upper¶
upper = ta.bb_upper(close, length, mult)
Bollinger upper band.
ta.bb_lower¶
lower = ta.bb_lower(close, length, mult)
Bollinger lower band.
Signals¶
ta.crossover¶
if ta.crossover(fast, slow) {
signal = 1
}
Available in both indicators and robots. Returns true when the current first-series value is greater than the second-series value, and the previous first-series value was less than or equal to the previous second-series value.
ta.crossunder¶
if ta.crossunder(fast, slow) {
signal = -1
}
Available in both indicators and robots. Returns true when the current first-series value is less than the second-series value, and the previous first-series value was greater than or equal to the previous second-series value.
Signal Arguments and Warmup¶
Both signal functions require exactly two positional named series, such as fast, slow, or close. Inputs, scalar constants, history offsets (fast[1]), inline expressions, and named arguments are not accepted. Calculate an intermediate series first when needed.
If any of the four current/previous values is missing, null, or non-finite, the result is false. This prevents signals during moving-average warmup. Signals on a forming candle may change before it closes; plotText excludes that candle by default.
For a complete indicator, see MA crossover labels.
Periods, warmup and independent state¶
Periods are finite safe integers from 1 to 10,000. Each static ta.* call site has independent state, even when two calls have the same period but different sources. State resets on every history evaluation.
SMA, sum, highest, lowest, standard deviation and Bollinger functions need a complete finite window; otherwise they return null. Standard deviation uses the population divisor (window length). EMA and RMA start from the first finite input, rather than an initial SMA. Missing input returns null and retains their previous smoothing state. This seed convention can produce different warmup values from Pine Script.
True range and ATR¶
ta.tr()= maximum ofhigh-low,abs(high-previousClose),abs(low-previousClose); the first candle useshigh-low.ta.atr(length)applies RMA to true range, seeded from the first finite true range.
script("ATR envelope", kind="indicator")
input length = 14
input factor = 2
range = ta.atr(length)
upper = close + range * factor
lower = close - range * factor
plot(upper)
plot(lower)
Confirmed pivots¶
ta.pivothigh(source, left, right) and ta.pivotlow(source, left, right) return the price of a pivot only on the candle that confirms it, right bars after the pivot candle. Before confirmation, or with incomplete/non-finite data, they return null. left and right must be integers from 1 to 100. Equal extrema choose the rightmost occurrence.
script("Confirmed swing highs", kind="indicator")
input strength = 3
pivot = ta.pivothigh(high, strength, strength)
if isClosed and not na(pivot) {
draw.label("high" + barIndex, barIndex - strength, pivot, "HH")
}
The label is anchored to the earlier candle but becomes known only at confirmation. On the forming confirmation candle a pivot may disappear; guard with isClosed for confirmed output.
Extreme offsets¶
ta.highestbars(source, length) and ta.lowestbars(source, length) return a nonnegative lookback offset, with 0 meaning the current candle. Ties select the rightmost extreme. A full finite window is required; otherwise the result is null. This sign convention must not be assumed to match Pine Script.
Classification features and kernels¶
| Function | Semantics |
|---|---|
ta.rsi(source, length) |
RSI 0–100; Wilder gain/loss averages seeded by an initial SMA; loss=0 returns 100 |
ta.cci(source, length) |
CCI with mean absolute deviation; a flat window returns zero |
ta.wt(source, channel, average) |
Raw WaveTrend difference WT1 - SMA(WT1,4); internal EMAs are SMA-seeded |
ta.adx(length) |
ADX 0–100 from OHLC, Wilder sums and SMA-seeded RMA of DX |
ta.normalize(value) |
Causal running min/max normalization to 0–1; a constant range returns zero |
ta.kernelGaussian(source, bandwidth, window) |
Gaussian weighted past-only Nadaraya–Watson estimate |
ta.kernelRQ(source, bandwidth, relativeWeight, window) |
Rational quadratic past-only Nadaraya–Watson estimate |
All arguments are positional. Periods/window are integers 1..500. Bandwidth is (0,500], relativeWeight (0,100]. Each call site has isolated state. Changing RSI/CCI/WT/ADX periods restarts their warmup. Missing/incomplete feature input yields null. Running normalization never examines future values; its state resets on replay.
Kernels use the available past at startup, up to window samples including the current candle. Gaussian weights are exp(-offset²/(2*bandwidth²)); RQ weights are (1+offset²/(2*bandwidth²*relativeWeight))^(-relativeWeight). A missing value in the active kernel window returns null.
These feature seed conventions do not change legacy ta.ema/ta.rma. ADX uses previous OHLC=0 on the first candle, matching the public reference convention without tick quantization. Flat-window CCI and WT differences are zero; flat RSI is 100 when averaged losses are zero.
Component vectors are checked against the public AI Edge Python reference, commit 75569fa; this does not establish full Pine signal parity. See ML classifier.
Money flow and volume-weighted price¶
ta.mfi(length) returns MFI in 0–100. Typical price is (high+low+close)/3; abs(typical price*volume) is classified by comparison with the previous typical price. The first loaded bar contributes neutral flow. Positive/(positive+negative) flow is scaled by 100. A flat valid window returns 50.
ta.vwma(source, length) returns the volume-weighted mean of source. Zero-volume bars in a nonzero window contribute zero weight.
Both functions take positional arguments with integer length 1–500. They require a complete valid window. Missing/negative volume invalidates the window; zero-total-volume windows return null. They never substitute price for missing volume. Numeric overflow returns null. Changing length restarts warmup.
script("Money flow", kind="indicator")
value = ta.mfi(14)
pane(title="MFI", min=0, max=100)
plot(value)