Documentation/Expressions
Expression rules and syntax
Assignments, comments and series semantics.
Each line is either a comment (#) or an assignment name = expression. Every value is a series aligned to the candle index; warm-up periods are NaN and NaN compares as false.
# comments start with #
ma20 = ta_ma(close, 20)
signal = crossover(close, ma20) and volume > ta_ma(volume, 20)Base variables
- open
- high
- low
- close
- volume
- funding_rate
- open_interest
- liquidations
- active_addresses
- fear_greed
- market_temperature
- risk_score
Functions
| Function | Description |
|---|---|
| ta_ma(x, n) | Simple moving average |
| ta_ema(x, n) | Exponential moving average |
| ta_rsi(x, n) | Relative strength index |
| ta_atr(n) | Average true range |
| ta_std(x, n) | Rolling standard deviation |
| ta_max(x, n) | Rolling maximum |
| ta_min(x, n) | Rolling minimum |
| ta_sum(x, n) | Rolling sum |
| ta_roc(x, n) | Rate of change (%) |
| ta_zscore(x, n) | Rolling z-score |
| ta_bb_upper(x, n, k) | Bollinger upper band |
| ta_bb_lower(x, n, k) | Bollinger lower band |
| ta_macd(x, fast, slow) | MACD line |
| ta_macd_signal(x, fast, slow, sig) | MACD signal line |
| ta_adx(n) | Average directional index |
| ta_kdj_k(n, m1, m2) | KDJ K line |
| ta_kdj_d(n, m1, m2) | KDJ D line |
| ta_obv() | On-balance volume |
| ta_supertrend(n, mult) | Supertrend line (ATR bands) |
| ta_supertrend_dir(n, mult) | Supertrend direction: 1 bullish, -1 bearish |
| ta_cci(n) | Commodity channel index |
| ta_willr(n) | Williams %R (-100..0) |
| ta_mfi(n) | Money flow index (volume-weighted RSI) |
| ta_donchian_upper(n) | Donchian channel upper band (highest high) |
| ta_donchian_lower(n) | Donchian channel lower band (lowest low) |
| ta_ret(x, n) | Simple return over n bars (fraction) |
| ta_ma_slope(x, n, lag) | MA slope: % change of the n-MA over `lag` bars |
| ta_typical() | Typical price (H+L+C)/3 |
| ta_vwap(n) | Rolling VWAP |
| shift(x, n) | Lag a series by n bars |
| crossover(a, b) | 1 when a crosses above b |
| crossunder(a, b) | 1 when a crosses below b |
| where(cond, a, b) | Element-wise conditional |
| abs(x) | Element-wise math |
| max(a, b) | Element-wise max / min |
| cs_rank(x) | Cross-sectional percentile rank across all symbols (0..1) |
| cs_zscore(x) | Cross-sectional z-score across symbols |
| cs_demean(x) | x minus the cross-sectional mean |
| cs_scale(x) | x / sum(|x|) across symbols (weights sum to 1) |
| cs_mean(x) | Cross-sectional mean (universe average) |
| htf("1d", expr) | Evaluate expr on a higher timeframe (last completed period, no look-ahead) |
Cross-sectional functions
cs_rank, cs_zscore, cs_demean, cs_scale and cs_mean look across every symbol in the data source at the same bar. They are what factor-selection strategies need: rank by a normalised score instead of a raw value.
mom = ta_roc(close, 42)
score = cs_zscore(mom) # z-score across the universe
top = cs_rank(score) >= 0.8 # top 20% of symbolsHigher timeframes
htf("1d", expr) evaluates expr on candles resampled to the given period and maps the value of the last completed period back to every base bar, so a 4h strategy can read a daily trend without look-ahead. OHLCV is resampled properly; upstream columns are available too (their last value in each period). Increase the lookback to cover the longer window.
daily_ma = htf("1d", ta_ma(close, 20))
weekly_high = htf("1w", ta_max(high, 4))
trend_ok = close > daily_ma