Built-in Functions
The ta, math, time and data namespaces, and what each family of function returns.
The ta namespace covers technical analysis. Moving averages are ta.sma, ta.ema, ta.wma, ta.rma, ta.hma and ta.vwma. Oscillators include ta.rsi, ta.stoch, ta.cci, ta.mfi and ta.macd, which returns a tuple of line, signal and histogram that you destructure on assignment. Volatility is ta.atr, ta.stdev, ta.bbands and ta.keltner.
Structural helpers are the ones you reach for most often in real scripts: ta.highest and ta.lowest over a window, ta.crossover and ta.crossunder between two series, ta.barsSince a condition, ta.valueWhen a condition was last true, ta.pivotHigh and ta.pivotLow with left and right bar counts, and ta.change for the bar-over-bar difference. Volume-anchored measures live at ta.vwap and ta.obv.
Three more ta functions are easy to misread, so here they are exactly. ta.cum(x) is a running total of x from the first bar of the data set: ta.cum(volume) is cumulative volume, ta.cum(1) is a bar counter, and a rolling window sum is the difference of two of them, total - total[len]. Because it accumulates from wherever the data happens to begin, only its shape and its differences carry information and never its level, which is why cumulative indicators are plotted with an arbitrary starting value. ta.dev(src, len) is the mean absolute deviation: the average of the absolute distances between each of the last len values and the current moving average of that same window. It is not a standard deviation — nothing is squared, so a single outlier moves it far less — and it is the denominator the Commodity Channel Index divides by, alongside the 0.015 scaling constant. ta.percentrank(src, len) reports where the current value sits in its own recent distribution, as the percentage of the last len values that are below it, so it runs 0 to 100 and assumes nothing about the shape of that distribution.
The math namespace is the plain numeric layer: abs, min, max, round, floor, ceil, pow, sqrt, log, exp, sign, clamp and sum. These operate elementwise on series and on scalars alike. math.round takes an optional precision, and clamp is the polite way to keep an input-derived multiplier inside a sane range.
The time namespace answers calendar questions: time.within a session window, time.crossed a boundary, time.dayOfWeek, time.hour, time.minute, time.isMonthEnd and time.since a timestamp. Sessions are expressed in the exchange local time of the symbol, not in yours, which is what makes an equities window like 09:30 to 15:45 behave correctly across daylight saving changes.
The data namespace requests values from another timeframe. data.request takes a timeframe and an expression and evaluates that expression on the requested timeframe, returning the last confirmed value. Keep requested expressions small — request the finished indicator, not the raw source you then recompute — because each request adds a second evaluation pass over the higher timeframe bars.
Example
AlgoBeamScript — inputs and settings
//@version=2
indicator("Volatility Bands", overlay = true, pane = "main")
group.settings("Calculation")
len = input.int(20, "Length", minval = 2, maxval = 500, step = 1)
mult = input.float(2.0, "Band width", minval = 0.25, step = 0.25)
src = input.source(hlc3, "Source")
method = input.enum("EMA", "Average", options = ["SMA", "EMA", "WMA", "RMA"])
group.settings("Display")
showFill = input.bool(true, "Shade the channel")
bandColor = input.color(color.accent, "Band color")
offset = input.int(0, "Offset", minval = -50, maxval = 50)
higherTf = input.timeframe("1D", "Anchor timeframe")
basis = method == "SMA" ? ta.sma(src, len)
: method == "EMA" ? ta.ema(src, len)
: method == "WMA" ? ta.wma(src, len)
: ta.rma(src, len)
dev = mult * ta.stdev(src, len)
daily = data.request(higherTf, ta.atr(14))
// offset shifts the drawn line along the time axis and changes no value:
// positive draws it forward, negative back.
plot(basis + dev, title = "Upper", color = bandColor, offset = offset)
plot(basis - dev, title = "Lower", color = bandColor, offset = offset)
plot(basis, title = "Basis", color = color.fg_subtle, style = plot.dashed,
offset = offset)
fill(basis + dev, basis - dev, color = color.fade(bandColor, 92), when = showFill)
label.value("Daily ATR", daily, corner = corner.top_right)Copy it, change one input, and run it again — the numbers are deterministic, so a difference in the output is always a difference you made.