Appearance

Personalize your experience

Mode
Accent Color
Direction
All Docs/QuaScript//
QuaScript logo

QuaScript Documentation

Language guide, engine API, 601 builtins and the preset library · v3.0.0-phase1

Rendering

Outputs are declared by render.* calls. Each call is one output; calling it on every bar gives it one value per bar. The backend (canvas, WebGL or WebGPU) is never part of a name: it comes from the header's render setting or a call's backend argument.

Backends

QuaScriptengine result
Loading the engine result…
webgpu.qs
analysis "Trend ribbon" { overlay = true, render = webgpu }
fast = ta.ema(close, 9)
slow = ta.ema(close, 34)
render.line(fast, "Fast", color = fast > slow ? color.emerald.400 : color.rose.400, width = 2)
render.line(slow, "Slow", color = color.translucent(color.amber.400, 40), width = 6)
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)
render / backendChart behaviour
auto (default)the chart chooses Canvas 2D or WebGL by data size
canvasCanvas 2D
webglWebGL2
webgpuWebGPU: lines, steps, splines, baselines, areas, bands, histograms and marks are drawn in one GPU pass (4x MSAA); clouds, labelled marks, levels and profiles stay on Canvas 2D in the same z-order. Until the browser's WebGPU device is ready, or where WebGPU is unavailable, the chart draws the script with WebGL / Canvas 2D.

backend = "webgpu" on one call (for example render.line(x, backend = "webgpu")) asks for WebGPU for the whole script on the chart.

Plots

QuaScriptengine result
Loading the engine result…
plots.qs
analysis "Plot styles" { overlay = false }

m = ta.rsi(close, 14) - 50
render.line(m, "Line", color = color.sky.400, width = 2)
render.spline(ta.ema(m, 5), "Spline", color = color.violet.400)
render.step(math.round(m / 10) * 10, "Step", color = color.amber.400)
render.histogram(m, "Histogram", color = m >= 0 ? color.teal.500 : color.rose.500)
render.area(m, "Area", base = 0, color = color.translucent(color.sky.500, 80))
render.baseline(m, "Baseline", base = 0, up_color = color.emerald.500, down_color = color.rose.500)
render.dots(ta.pivot_high(5, 5, m), "Dots", shape = shape.circle, size = 3, color = color.white)
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)
FunctionDraws
render.linea polyline
render.splinea smoothed curve
render.stepa staircase line
render.area / render.stepped_areaa filled area down to base
render.histogramcolumns from base
render.baselinea line colored above / below base
render.dotsa shape per bar

Shared arguments: title, color, width, stroke (style.solid, style.dashed, style.dotted), pane, offset (shift in bars), backend.

  • na values are gaps.
  • Per-bar colors: when color is an expression (m >= 0 ? a : b), every bar gets its own color. Lines change color segment by segment; histograms and dots color each point.
  • pane = 1 puts the output in the script's lower pane, pane = 0 on the price pane.

Panes

A chart has two kinds of panes, and a script can draw in both.

PaneSharesx axisy axisDeclared by
price panetimepricepane = price (default)
H pane (horizontal)the time axistimethe script's own scalepane = hpane
V pane (vertical)the price scalea value at each pricepricepane = vpane and render.vpane.*

H panes stack under the price pane, one per script; height sets its share of the chart. Plots go to the script's pane by default; pane = pane.price (0) or pane = pane.lower (1) on a call overrides it.

QuaScriptengine result
Loading the engine result…
hpane.qs
analysis "Flow monitor" {
    pane   = hpane
    height = 0.3
}
(buy, sell, imb) = hft.flow(50)
render.histogram(imb, "Imbalance", color = imb >= 0 ? color.emerald.500 : color.rose.500)
render.line(hft.vpin(50), "VPIN", color = color.fuchsia.400)
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)

V panes are columns beside the price axis. Each row is level with the same price on the chart, so a V pane reads as "how much of something happened at this price".

QuaScriptengine result
Loading the engine result…
vpane.qs
analysis "Delta at price" {
    pane  = vpane
    width = 150
}
(buy, sell, imb) = hft.flow(20)
// buy volume right, sell volume left, spread over each bar's range
render.vpane.histogram(buy, value2 = sell, low = low, high = high, title = "Buy | Sell")
// the net delta at each close, averaged instead of summed
render.vpane.histogram(buy - sell, price = close, aggregate = "mean", title = "Mean delta")
// one of the chart's built-in V panes
render.vpane.profile(kind = "tpo", width = 110)
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)

render.vpane.histogram(value, ...) records one contribution per bar; the chart sums them by price:

ArgumentDefaultMeaning
priceclosethe row the value lands in
low, highspread the value over [low, high] in proportion to the overlap (set both)
value2a second value drawn mirrored on the left (e.g. sell beside buy)
periodvisiblevisible bars, the current session, the last bars, or all history
aggregatesumsum, mean, count, max, min or last per row
rows, row_size60, 0rows across the visible price range, or a fixed price step
color, color2positive / second (or negative) values
show_poc, poc_color, show_value_area, value_area, extend_pocpoint of control and value area of the rows; extend_poc draws them across the chart
title, width, anchor, labelspane header, width in px, bars grow from the axis (left) or the outer edge (right), row labels

Negative values are drawn to the left of a centre line in color2. na values add nothing.

render.vpane.profile(kind = ...) adds one of the chart's own V panes, computed by the chart from its bars (and its order book for the book kinds): volume, buy_sell, delta, session, composite, tpo, time_at_price, close, wick, sr_strength, volatility, nodes, orderbook, depth, imbalance, liquidity.

V panes are incremental like everything else: on a live tick the chart re-adds only the forming bar, a new candle adds one bar, and panning moves the window by the bars that entered or left it. A script with pane = vpane may also draw plots; they go to the price pane.

Bands

QuaScriptengine result
Loading the engine result…
bands.qs
analysis "Bands" { overlay = true }

(mid, up, dn) = ta.bollinger(close, 20, 2.0)
pu = render.line(up, "Upper", color = color.slate.500)
pd = render.line(dn, "Lower", color = color.slate.500)
render.band(pu, pd, color = color.sky.500, opacity = 0.1)

(conv, base, a, b, lag) = ta.ichimoku()
pa = render.line(a, "Span A", color = color.emerald.500, offset = 26)
pb = render.line(b, "Span B", color = color.rose.500, offset = 26)
render.band(pa, pb, texture = "cloud", upper_color = color.emerald.500, lower_color = color.rose.500, opacity = 0.25)
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)

render.band(top, bottom) fills between two plot handles (the value returned by a plot or a level). texture is flat (default), gradient (upper_color → lower_color, optional mid_color) or cloud (cloud_style, puff_scale).

Gradient bands

Three ways to color a band with the data:

  • color = <series> gives every bar its own flat fill color (heatmap rows).
  • direction sets where a constant gradient runs: vertical (default) spans the band's whole height on screen, horizontal runs left to right, and edges runs from each bar's own top edge to its own bottom edge, so a sloping or widening channel keeps its colors on its edges.
  • upper_color and lower_color may be series. Each bar then fades from its own top color to its own bottom color (an edge-anchored gradient with per-bar colors), and the GPU blends neighbouring bars smoothly.
QuaScriptengine result
Loading the engine result…
gradient_bands.qs
analysis "Gradient bands" {
    overlay = true
    render  = webgpu
}
m = ta.ema(close, 34)
a = ta.atr(34)
z = (close - m) / a
pu = render.line(m + 2 * a, "Upper", color = color.slate.500, width = 1)
pl = render.line(m - 2 * a, "Lower", color = color.slate.500, width = 1)
// per-bar edge colors: the top edge shows the stretch on a perceptual palette
render.band(pu, pl, upper_color = color.ramp(z, -2, 2, "turbo"), lower_color = color.transparent, opacity = 0.45, title = "Stretch")
// constant colors anchored to each bar's edges
pi = render.line(m + a, "Inner", color = color.transparent, width = 0)
render.band(pu, pi, texture = "gradient", direction = "edges", upper_color = color.rose.400, lower_color = color.slate.900, opacity = 0.25, title = "Upper zone")
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)

Both the WebGPU and the Canvas 2D renderer draw these gradients the same way.

Levels, time marks, backgrounds, candle colors

QuaScriptengine result
Loading the engine result…
levels.qs
analysis "Levels" { overlay = false }

r = ta.rsi(close, 14)
render.line(r, "RSI")
ob = render.level(70, "Overbought", color = color.rose.600)
os = render.level(30, "Oversold", color = color.teal.600)
render.band(ob, os, color = color.violet.500, opacity = 0.05)
render.time_mark(time.weekday() == 1 and time.weekday(time[1]) != 1, "Week start")
render.background(r > 70 ? color.translucent(color.rose.500, 90) : na)
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)
  • render.level(price) is a horizontal line at a constant (or parameter) price.
  • render.time_mark(when) draws a vertical line on the bars where when is true.
  • render.background(color) tints the bar's background; na leaves it.
  • render.candle_color(color) colors the price candle of the bar.

Marks

QuaScriptengine result
Loading the engine result…
marks.qs
analysis "Marks" { overlay = true }

f = ta.ema(close, 9)
s = ta.ema(close, 21)
render.mark(ta.cross_up(f, s), shape = shape.tag_up, at = anchor.below_bar, color = color.emerald.500, text = "Buy")
render.mark(ta.cross_down(f, s), shape = shape.tag_down, at = anchor.above_bar, color = color.rose.500, text = "Sell")
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)

A mark is drawn on every bar where when is true. Shapes: arrow_up arrow_down circle cross diamond square tag_up tag_down triangle_up triangle_down star flag plus x pin tag. Positions (at): anchor.above_bar, anchor.below_bar, anchor.top, anchor.bottom, or anchor.price with price = ....

Price styles

render.price.candles, bars, hollow, heikin, renko, kagi, point_figure and line_break draw price bars computed by the script (or the chart's own bars by default):

QuaScriptengine result
Loading the engine result…
price_styles.qs
analysis "Delta candles" { overlay = false }

d = volume * (close > open ? 1 : -1)
persist cum = 0.0
o = cum
cum := cum + d
render.price.candles(o = o, h = math.max(o, cum), l = math.min(o, cum), c = cum, up_color = color.teal.500, down_color = color.rose.500)
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)

Profiles

QuaScriptengine result
Loading the engine result…
profile.qs
analysis "Volume profile" { overlay = true, render = webgl }

rows = param.int(70, title = "Rows", min = 8, max = 400)
render.profile.volume(rows = rows, value_area = 0.7, width = 160)
quatick-charts · QuaScript engine on synthetic 1-minute bars · drag to pan · scroll to zoom · Run executes the script on the engine (⌘/Ctrl+Enter while editing)

render.profile.volume (visible range), render.profile.session (per session) and render.profile.tpo are computed by the engine, including the point of control and value area. ta.volume_profile() returns the developing POC / VAH / VAL as series for trading against.

Colors

See Colors for the palette and color functions.


© 2026 Quatick Technologies. All rights reserved.