Introduction
Some indicators produce more than one line. Bollinger Bands give you an upper band, a basis, and a lower band. MACD gives a MACD line, a signal line, and a histogram. In kScript these multi-output indicators return a single result whose components you read by name:
//@version=2
define(title="Bollinger bands", position="overlay", axis=true)
timeseries d = ohlcv(symbol=currentSymbol, exchange=currentExchange)
var bands = bb(source=d.close, period=20, mult=2)
plotLine(value=bands.upper, colors=["#2563eb"], width=2, label=["BB upper"], desc=["upper Bollinger band"])
plotLine(value=bands.basis, colors=["#64748b"], width=2, label=["BB basis"], desc=["Bollinger basis (the moving average)"])
plotLine(value=bands.lower, colors=["#2563eb"], width=2, label=["BB lower"], desc=["lower Bollinger band"])bb(...) hands back a Bollinger result; bands.upper, bands.basis, and bands.lower are its three lines. You name what you want. There is no "is the upper band index 0 or index 2?" guesswork, and a typo like bands.upperr is a compile error rather than a silently-wrong line.
How it works
A multi-output builtin returns one value that carries several named series. Read a component with a dot, exactly like an OHLCV field (d.close). Each component is an ordinary series, so it flows straight into math, other indicators, conditions, and plots:
var m = macd(source=d.close, fastPeriod=12, slowPeriod=26, signalPeriod=9)
var risingMomentum = m.histogram > m.histogram[1] // compare bars
var smoothSignal = ema(source=m.signal, period=5) // feed into another indicatorYou can keep the whole result in one var and pull fields as needed, or read a single field inline when that is all you use.
The named streams
These are the multi-output builtins and the field names each one exposes:
| Builtin | Fields |
|---|---|
bb | .upper, .basis, .lower |
keltner | .upper, .basis, .lower |
macd | .macd, .signal, .histogram |
stoch | .k, .d |
supertrend | .line, .direction |
A few worth calling out:
stochsplits into the fast%K(.k) and its smoothed%D(.d). The classic crossover isstoch.kcrossingstoch.d.supertrendreturns the trailing stop level as.lineand the trend side as.direction. Use.directionto color or gate; use.lineto draw the stop.macd.histogramis the MACD line minus the signal line, ready to plot as bars.
Reading every stream at once
This script reads all five multi-output indicators and plots each of their named components.
//@version=2
define(title="Named Stream Members", position="offchart", axis=true)
timeseries trade = ohlcv(symbol=currentSymbol, exchange=currentExchange)
timeseries closeSeries = trade.close
var bands = bb(source=closeSeries, period=20, mult=2)
var macdValue = macd(source=closeSeries, fastPeriod=12, slowPeriod=26, signalPeriod=9)
var stochValue = stoch(periodK=14, smoothK=3, periodD=3)
var keltnerValue = keltner(source=trade, period=20, mult=1.5, atrPeriod=10)
var trendValue = supertrend(factor=3, atrPeriod=10)
plotLine(value=bands.upper, colors=["#2563eb"], width=2, label=["BB upper"], desc=["bb.upper named stream"])
plotLine(value=bands.basis, colors=["#64748b"], width=2, label=["BB basis"], desc=["bb.basis named stream"])
plotLine(value=bands.lower, colors=["#dc2626"], width=2, label=["BB lower"], desc=["bb.lower named stream"])
plotLine(value=macdValue.macd, colors=["#1d4ed8"], width=2, label=["MACD"], desc=["macd.macd named stream"])
plotLine(value=macdValue.signal, colors=["#ea580c"], width=2, label=["Signal"], desc=["macd.signal named stream"])
plotLine(value=macdValue.histogram, colors=["#15803d"], width=2, label=["Histogram"], desc=["macd.histogram named stream"])
plotLine(value=stochValue.k, colors=["#0891b2"], width=2, label=["Stoch K"], desc=["stoch.k named stream"])
plotLine(value=stochValue.d, colors=["#be123c"], width=2, label=["Stoch D"], desc=["stoch.d named stream"])
plotLine(value=keltnerValue.upper, colors=["#16a34a"], width=2, label=["Keltner upper"], desc=["keltner.upper named stream"])
plotLine(value=keltnerValue.basis, colors=["#94a3b8"], width=2, label=["Keltner basis"], desc=["keltner.basis named stream"])
plotLine(value=keltnerValue.lower, colors=["#b91c1c"], width=2, label=["Keltner lower"], desc=["keltner.lower named stream"])
plotLine(value=trendValue.line, colors=["#7c3aed"], width=2, label=["Supertrend line"], desc=["supertrend.line named stream"])
plotLine(value=trendValue.direction, colors=["#111827"], width=2, label=["Supertrend direction"], desc=["supertrend.direction named stream"])What to expect: each band-style indicator (bb, keltner) starts drawing once its lookback window fills, and the three lines track together. macd produces its three components in lockstep. supertrend.line is a price-level series while supertrend.direction flips between trend states.