Language Overview
The shape of an AlgoBeamScript file: pragma, declaration, types, operators and functions.
AlgoBeamScript is a small declarative language for describing what to compute on each bar and what to draw. Every file opens with a version pragma, then exactly one declaration — indicator or strategy — that names the script and sets its chart-level options. Everything after that is inputs, series and output, in whatever order reads best.
Types are int, float, bool, string, color and series. Type annotations are optional on assignment and required on function parameters. The series keyword marks a value that carries history and can be indexed backwards; a plain assignment still produces a series when its right-hand side does, so the keyword is documentation as much as declaration. The one keyword that changes behaviour rather than describing it is var, which marks a value initialised once and then carried from bar to bar — Variables and State covers when that is the thing you want.
Operators are the usual arithmetic and comparison set, with and, or and not spelled as words, and a ternary condition ? a : b. Arithmetic between two series is elementwise, and a series combined with a scalar broadcasts the scalar. Indexing with square brackets reaches into history: emaF[3] is the value three bars ago, and a negative index is a compile error because looking forward is not permitted. Assignment comes in two spellings and they are not interchangeable: = introduces a name, := assigns to a name that already exists.
Control flow is deliberately thin. There is if and else if, a counted for loop over a range, a while loop for the rare case where the iteration count is not known in advance, and functions declared with fn that take typed parameters and return a value with return. A block is written either indented under its header or wrapped in braces. Functions may compute series and call into the standard library, but they may not declare inputs or emit plots, which keeps the settings panel and the chart output statically knowable; Loops and Functions has the details.
The standard library lives in four namespaces — ta for technical analysis, math for numerics, time for sessions and calendars, and data for higher timeframe requests — alongside the input, plot, color and array helpers listed in the Language Reference. There is no import statement, no file access and no network access. A script is a pure function from bars to output, which is exactly why the same file runs in a browser tab, in the CLI and inside a server process.
Example
AlgoBeamScript — Momentum Ribbon indicator
//@version=2
indicator("Momentum Ribbon", overlay = true, precision = 2)
// ---- inputs --------------------------------------------------------
len = input.int(14, "RSI length", minval = 2, maxval = 200)
fast = input.int(21, "Fast EMA", minval = 2)
slow = input.int(55, "Slow EMA", minval = 5)
span = input.int(8, "Weighted window", minval = 2, maxval = 100)
level = input.float(55.0, "Bull threshold", step = 0.5)
src = input.source(close, "Source")
// ---- series --------------------------------------------------------
series r = ta.rsi(src, len)
series emaF = ta.ema(src, fast)
series emaS = ta.ema(src, slow)
series slope = (emaF - emaF[3]) / 3
// A linearly weighted average written out longhand. The accumulator is
// declared with = before the loop and updated with := inside it; it is a
// plain local rather than a var, so it starts again from zero every bar.
weighted = 0.0
for i = 0 to span - 1
weighted := weighted + (span - i) * src[i]
series pull = weighted / (span * (span + 1) / 2)
bull = r > level and emaF > emaS and slope > 0
bear = r < 100 - level and emaF < emaS and slope < 0
// ---- output --------------------------------------------------------
plot(emaF, title = "Fast", width = 2,
color = bull ? color.bull : bear ? color.bear : color.fg_subtle)
plot(emaS, title = "Slow", width = 1, color = color.fg_subtle)
plot(pull, title = "Weighted", width = 1, color = color.accent)
fill(emaF, emaS, color = color.fade(bull ? color.bull : color.bear, 88))
plot(r, title = "RSI", pane = "lower", color = color.accent, width = 2)
hline(level, "Bull", pane = "lower", style = line.dashed)
hline(100 - level, "Bear", pane = "lower", style = line.dashed)
alert.when(ta.crossover(r, level), "Ribbon flipped bullish on {symbol} at {close}")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.