Skip to main content
ATK Pine Script®

ta.* Function Reference

Technical analysis functions available in ATK PyneScript V6 — EMA, SMA, RSI, MACD, BBands, crossover, and more.

ta.* Namespace Overview#

The ta namespace provides a complete set of technical analysis functions that operate on pandas Series or DataFrame columns. All functions are designed to work inside build_indicator_frame or build_signal_frame — never inside build_visuals or build_trade_frame.

Moving Averages#

from source import ta

# Exponential Moving Average
ema_series = ta.ema(frame["close"], length=20)

# Simple Moving Average
sma_series = ta.sma(frame["close"], length=20)

# Running Moving Average (Wilder's)
rma_series = ta.rma(frame["close"], length=14)

# Weighted Moving Average
wma_series = ta.wma(frame["close"], length=20)

# Hull Moving Average
hma_series = ta.hma(frame["close"], length=20)

Momentum and Oscillators#

# Relative Strength Index
rsi_series = ta.rsi(frame["close"], length=14)

# MACD — returns (macd_line, signal_line, histogram)
macd, signal, hist = ta.macd(frame["close"], fast=12, slow=26, signal=9)

# Stochastic — returns (k, d)
k, d = ta.stoch(frame["high"], frame["low"], frame["close"], k=14, d=3, smooth_k=3)

# Average True Range
atr_series = ta.atr(frame["high"], frame["low"], frame["close"], length=14)

# Commodity Channel Index
cci_series = ta.cci(frame["high"], frame["low"], frame["close"], length=20)

Bollinger Bands#

# Returns (upper, basis, lower)
upper, basis, lower = ta.bbands(
    frame["close"],
    length=20,
    std=2.0,
    mamode="sma",
)

frame["ub"] = upper.reset_index(drop=True)
frame["cb"] = basis.reset_index(drop=True)
frame["lb"] = lower.reset_index(drop=True)

Crossover Signals#

# Returns boolean Series — True on the bar where fast crosses above slow
buy_signal = ta.crossover(ema_fast, ema_slow).fillna(False)

# Returns boolean Series — True on the bar where fast crosses below slow
sell_signal = ta.crossunder(ema_fast, ema_slow).fillna(False)

Always call .fillna(False) on crossover/crossunder results before using them in boolean conditions or np.where. The first few bars produce NaN due to lookback requirements.

Supertrend#

# Returns (supertrend_line, direction_series)
# direction: 1 = uptrend, -1 = downtrend
supertrend, direction = ta.supertrend(
    frame["high"], frame["low"], frame["close"],
    length=10,
    multiplier=3.0,
)

Usage Patterns#

Source Fallback Pattern#

Always implement a safe fallback when using input.source:

source_name = str(p.get("source_type", "close") or "close")
source_series = frame[source_name] if source_name in frame.columns else frame["close"]

frame["ema_value"] = ta.ema(source_series, int(p.get("length", 20) or 20))

Full Indicator Example#

import pandas as pd

from source import indicator, input, plot, ta


indicator("EMA Crossover", overlay=True, max_bars_back=240)
fast_length = input.int(10, title="Fast EMA", key="fast_length", minval=1)
slow_length = input.int(21, title="Slow EMA", key="slow_length", minval=2)


def build_indicator_frame(df: pd.DataFrame, params: dict | None = None) -> pd.DataFrame:
    frame = df.copy().reset_index(drop=True)
    p = {
        "fast_length": int(fast_length),
        "slow_length": int(slow_length),
    } | dict(params or {})

    frame["ema_fast"] = ta.ema(frame["close"], int(p["fast_length"]))
    frame["ema_slow"] = ta.ema(frame["close"], int(p["slow_length"]))
    frame["buy_signal"] = ta.crossover(frame["ema_fast"], frame["ema_slow"]).fillna(False)
    frame["sell_signal"] = ta.crossunder(frame["ema_fast"], frame["ema_slow"]).fillna(False)
    return frame

Stage Ownership Rules#

All ta.* calls belong in build_indicator_frame (indicators) or build_signal_frame (strategies). Never call ta.* inside build_visuals or build_trade_frame. Those stages consume already-computed columns — they do not run new calculations.

See also: