Built-in Functions
All functions are called via this inside calculate(). Functions that accept a source parameter take either a string series name ('close', 'hl2', etc.) or a direct numeric value.
Moving Averages
| Function | Signature | Description |
|---|---|---|
| sma | this.sma(source, period) | Simple Moving Average |
| ema | this.ema(source, period) | Exponential Moving Average |
| wma | this.wma(source, period) | Weighted Moving Average |
| rma | this.rma(source, period) | Running Moving Average (Wilder's smoothing) |
| smma | this.smma(source, period) | Smoothed Moving Average (alias for rma) |
| dema | this.dema(source, period) | Double EMA: 2 * EMA - EMA(EMA) |
| tema | this.tema(source, period) | Triple EMA: 3*EMA - 3*EMA(EMA) + EMA(EMA(EMA)) |
| hma | this.hma(source, period) | Hull MA: WMA(2*WMA(n/2) - WMA(n), sqrt(n)) — minimal lag |
| vwma | this.vwma(source, period) | Volume-Weighted MA |
| linreg | this.linreg(source, period) | Linear Regression end value |
Example: Comparing Moving Averages
const smaVal = this.sma('close', 20); // Smoothest, most lag
const emaVal = this.ema('close', 20); // Less lag than SMA
const hmaVal = this.hma('close', 20); // Least lag, may overshoot
const vwmaVal = this.vwma('close', 20); // Weighted by volumeCompound Indicators
These return objects with multiple values. Destructure or access properties directly.
macd(source, fast, slow, signal)
Returns { macd: number, signal: number, histogram: number }
const m = this.macd('close', 12, 26, 9);
plot('MACD', m.macd, { color: color.blue, width: 2 });
plot('Signal', m.signal, { color: color.orange });
plotHistogram('Histogram', m.histogram, {
color: m.histogram >= 0 ? color.green : color.red
});bbands(source, period, multiplier)
Returns { upper: number, middle: number, lower: number }
const bb = this.bbands('close', 20, 2);
plot('Upper', bb.upper, { color: color.blue, overlay: true });
plot('Middle', bb.middle, { color: color.gray, overlay: true });
plot('Lower', bb.lower, { color: color.blue, overlay: true });stoch(kPeriod, kSmooth, dSmooth)
Returns { k: number, d: number } (0-100 range)
const s = this.stoch(14, 3, 3);
plot('K', s.k, { color: color.blue, width: 2 });
plot('D', s.d, { color: color.orange });
hline('OB', 80, { color: color.red, style: 'dashed' });
hline('OS', 20, { color: color.green, style: 'dashed' });supertrend(period, factor)
Returns { value: number, direction: number } where direction is 1 (uptrend) or -1 (downtrend).
const st = this.supertrend(10, 3);
plotColor('SuperTrend', st.value,
[color.green, color.red],
st.direction === 1 ? 0 : 1,
{ width: 2 }
);Single-Value Indicators
| Function | Signature | Returns | Description |
|---|---|---|---|
| rsi | this.rsi(source, period) | 0-100 | Relative Strength Index |
| atr | this.atr(period) | number | Average True Range (uses H/L/C internally) |
| cci | this.cci(source, period) | number | Commodity Channel Index (use 'hlc3' for classic) |
| adx | this.adx(period) | 0-100 | Average Directional Index (trend strength) |
| mfi | this.mfi(period) | 0-100 | Money Flow Index (volume-weighted RSI) |
| obv | this.obv() | number | On Balance Volume (cumulative) |
| stdev | this.stdev(source, period) | number | Standard Deviation |
Range & Volatility
| Function | Signature | Returns | Description |
|---|---|---|---|
| highest | this.highest(source, period) | number | Highest value over N bars |
| lowest | this.lowest(source, period) | number | Lowest value over N bars |
| sum | this.sum(source, period) | number | Sum of values over N bars |
| trueRange | this.trueRange() | number | True Range: `max(H-L, |
| change | this.change(source, length?) | number | Current value minus value N bars ago (default: 1) |
| roc | this.roc(source, period) | number | Rate of Change %: (curr - prev) / prev * 100 |
| percentRank | this.percentRank(source, period) | 0-100 | Percentile rank over lookback period |
Utility Functions
Cross Detection
Important
crossOver and crossUnder require 4 arguments: current AND previous values for both series.
const fast = this.ema('close', 9);
const slow = this.ema('close', 21);
plot('Fast', fast); plot('Slow', slow);
// Use getPlot to get previous bar's values
const prevFast = this.getPlot('Fast', 1);
const prevSlow = this.getPlot('Slow', 1);
if (this.crossOver(fast, slow, prevFast, prevSlow)) {
this.log('Bullish crossover!');
}Condition Helpers
| Function | Signature | Returns | Description |
|---|---|---|---|
| barsSince | this.barsSince(condition) | number | Bars since condition was true (-1 if never) |
| valuewhen | this.valuewhen(condition, source, occurrence?) | number | Value of source when condition was last true |
| rising | this.rising(source, length) | boolean | True if source increased for N consecutive bars |
| falling | this.falling(source, length) | boolean | True if source decreased for N consecutive bars |
// How many bars since RSI crossed above 70?
const rsiVal = this.rsi('close', 14);
const barsSinceOB = this.barsSince(rsiVal > 70);
// What was the close when RSI last crossed 70?
const closeAtOB = this.valuewhen(rsiVal > 70, 'close');
// Is price rising for 3 consecutive bars?
const isRising = this.rising('close', 3);Math Functions
| Function | Description |
|---|---|
this.abs(value) | Absolute value |
this.max(a, b, ...) | Maximum of values |
this.min(a, b, ...) | Minimum of values |
this.round(value, decimals?) | Round to N decimal places |
Source Parameter
Functions that take a source parameter accept two forms:
String series names (from input.source() or directly):
'open','high','low','close','volume''hl2'= (high + low) / 2'hlc3'= (high + low + close) / 3'ohlc4'= (open + high + low + close) / 4- Plot names (reference your own plotted values)
- State keys (reference your own stored state)
Direct numeric values: this.close, this.high, or any computed number.
Both forms work correctly. Use input.source() when you want the user to choose the source in settings.

