Builtins: series maths
Every length must be a positive whole number. Window functions return nan until a complete window of finite values exists, which is normal at the left edge of the chart.
| Signature | Returns |
|---|---|
| ta.sma(source: float, length: int) -> float | Mean of a complete window |
| ta.ema(source: float, length: int) -> float | Exponential average, alpha 2 / (length + 1), seeded from the first finite value |
| ta.rma(source: float, length: int) -> float | Wilder average, alpha 1 / length |
| ta.wma(source: float, length: int) -> float | Linearly weighted mean, newest weighted length |
| ta.sum(source: float, length: int) -> float | Sum of a complete window |
| ta.variance(source: float, length: int) -> float | Population variance |
| ta.stdev(source: float, length: int) -> float | Square root of the population variance |
| ta.dev(source: float, length: int) -> float | Mean absolute deviation from the window mean |
| ta.highest(source: float, length: int) -> float | Maximum of a complete window |
| ta.lowest(source: float, length: int) -> float | Minimum of a complete window |
| ta.change(source: float [, length: int]) -> float | source minus source length bars ago, default 1 |
| ta.crossover(a: float, b: float) -> bool | a was at or below b and is now above |
| ta.crossunder(a: float, b: float) -> bool | a was at or above b and is now below |
| ta.cross(a: float, b: float) -> bool | Either of the two |
Indicators
The usual indicators, with the same names and arguments as Pine Script where Pine has them. len is a positive whole number of bars.
| Signature | Returns |
|---|---|
| ta.tr([handle_na: bool]) -> float | True range. On the first bar it is high minus low, or nan with false |
| ta.atr(len) -> float | Average true range, Wilder smoothed |
| ta.rsi(source, len) -> float | Relative strength index, 0 to 100 |
| ta.macd_line(source, fast, slow) -> float | Fast EMA minus slow EMA |
| ta.macd_signal(source, fast, slow, signal) -> float | EMA of the MACD line |
| ta.macd_hist(source, fast, slow, signal) -> float | Line minus signal |
| ta.bb_upper(source, len, mult) -> float, ta.bb_lower(...) | Bollinger bands: the SMA plus or minus mult standard deviations |
| ta.bb_width(source, len, mult) -> float | Band width as a percent of the SMA |
| ta.kc_upper(source, len, mult) -> float, ta.kc_lower(...) | Keltner channels: the EMA plus or minus mult times the EMA of the true range |
| ta.stoch(source, high, low, len) -> float | Stochastic, 0 to 100 |
| ta.cci(source, len) -> float | Commodity channel index |
| ta.mfi(source, len) -> float | Money flow index, 0 to 100 |
| ta.wpr(len) -> float | Williams %R, -100 to 0 |
| ta.cmo(source, len) -> float | Chande momentum oscillator, -100 to 100 |
| ta.tsi(source, short, long) -> float | True strength index, -1 to 1 |
| ta.plus_di(len) -> float, ta.minus_di(len) -> float | Directional indicators |
| ta.adx(di_len, adx_len) -> float | Average directional index |
| ta.supertrend(factor, atr_len) -> float | The SuperTrend line |
| ta.supertrend_dir(factor, atr_len) -> float | -1 in an up trend, 1 in a down trend |
| ta.psar(start, increment, maximum) -> float | Parabolic SAR |
| ta.obv() -> float | On balance volume |
| ta.cum(source) -> float | Running total since the first bar |
| ta.mom(source, len) -> float, ta.roc(source, len) -> float | Change over len bars, and the same as a percent |
| ta.rising(source, len) -> bool, ta.falling(source, len) -> bool | Above, or below, every one of the previous len values |
| ta.hma, ta.vwma, ta.dema, ta.tema(source, len) -> float | Hull, volume weighted, double and triple exponential averages |
| ta.alma(source, len, offset, sigma) -> float | Arnaud Legoux average |
| ta.swma(source) -> float | Symmetric weighted average of the last four values |
| ta.linreg(source, len, offset) -> float | Least squares line value, offset bars back from the newest |
| ta.correlation(a, b, len) -> float | Pearson correlation |
| ta.percentrank(source, len) -> float | Percent of the previous len values at or below this one |
| ta.median(source, len) -> float | Median of the window |
| ta.percentile_nearest(source, len, percent) -> float, ta.percentile_linear(...) | Percentile by nearest rank, or interpolated |
| ta.range(source, len) -> float | Highest minus lowest |
| ta.pivothigh([source,] left, right) -> float, ta.pivotlow(...) | The pivot value, on the bar right bars after it, otherwise nan |
| ta.barssince(condition) -> float | Bars since the condition was last true, 0 on that bar, nan before it ever was |
| ta.highestbars(source, len) -> float, ta.lowestbars(...) | Offset of the extreme, 0 or negative |
| ta.valuewhen(condition, source, occurrence) -> float | source on the bar of an earlier true condition, 0 being the latest |
| ta.avg_when(condition, source, n) -> float, ta.sum_when(...) | Average or sum of source over the last n bars where the condition was true, n from 1 to 500 |
| ta.vwap() -> float | The session VWAP the chart draws, reset at 18:00 New York |
| ta.vwap_band(k: int) -> float | That VWAP plus k standard deviations, k from -3 to 3 |
- They follow Pine Script: ta.rsi, ta.atr and the directional indicators use Wilder smoothing seeded with a simple average, and ta.ema is seeded with the first value. ta.rma on its own is seeded with the first value, as it always was.
- A nan anywhere in a window gives nan for that window, where Pine skips na in some functions.
- ta.pivothigh and ta.pivotlow confirm late: the pivot is reported right bars after the bar it happened on, and equal neighbours are not a pivot.
- ta.supertrend_dir is -1 in an up trend, as in Pine. Both SuperTrend calls are nan while the ATR warms up.
- ta.median and the percentiles take windows up to 1,000 bars.
- ta.valuewhen, ta.avg_when and ta.sum_when must be called on every bar with the condition, not from inside an if.
These read the value you pass on each bar at that call site. Put the call where it runs on every bar, at the top level, so its window is continuous. A call inside an if branch, or inside one arm of ? :, only samples the bars where it runs. They cannot be called inside a loop.
let fast: float = ta.ema(close, 9)
let slow: float = ta.ema(close, 21)
let crossed_up: bool = ta.crossover(fast, slow)
let spread_of_closes: float = ta.dev(close, 20)