Terminal documentation

Quasar Trading Terminal and the QuasarGen Script indicator language

QuasarGen Script: the indicator language

How the language works, how an indicator is computed and how to write your first one.

QuasarGen Script (QGS) is the language indicators are written in. Files use the .qgs extension, and the language version is declared on the first line: //@version=1.

The main property of the language is that there is nothing in it to do harm with. No files, no network, no pointers, no system calls: they simply do not exist in the language. Reviewing somebody else's indicator is therefore reading forty lines of formula, not hunting for a backdoor in two thousand lines of C++.

How it is computed

As in Pine: every value is a series over bars. The script describes what the value equals on the current bar, and the terminal runs it over the whole history itself, then computes new bars one at a time without recalculating the past.

The past is reached through [k]: close[1] is the previous bar's close. The depth must be a constant — then the memory for history is known before the first bar.

Every node is computed exactly once per bar. That is not an optimisation but a rule: state lives inside the ta.* functions — a window, a running average — and a second call on the same bar would move the window forward.

Both branches of ?: are always computed. Otherwise the history of the branch not taken would tear, and the indicator would depend on which bars happened to be computed.

na means “there is no value”. Until the window fills, the indicator honestly returns na, and the chart draws a gap instead of a zero.

Your first indicator

//@version=1
indicator("Two averages", overlay=true)

length = input.int("Period", 14, 1, 500)
fast = ta.ema(close, length)
slow = ta.sma(close, length * 3)

f = plot(fast, "EMA", color.bull, width=2)
s = plot(slow, "SMA", color.text)
fill(f, s, color.bull, opacity=20)

Names may be written in any language — the language works in Unicode. The input.int(...) line does more than set the period: the terminal builds the indicator's settings form out of it, so the form and the script cannot drift apart.

An indicator in its own pane

//@version=1
indicator("RSI", overlay=false, precision=2)

length = input.int("Period", 14, 2, 200)
value = ta.rsi(close, length)

plot(value, "RSI", color.accent, width=2)
hline(70, "Overbought", color.sell)
hline(30, "Oversold", color.bull)

overlay=false means a separate pane under the chart: an oscillator has its own scale, and laying it over prices makes no sense.

Shifting lines and filling

offset in plot shifts the line by bars: forward (+) or back (−). What moves is the position on the chart, not the values — the computation stays tied to its own bar. fill takes two colours: the first when the first line is above the second, the second when it is below. Together that gives the Ichimoku cloud:

tenkan = (ta.highest(high, 9) + ta.lowest(low, 9)) / 2
kijun = (ta.highest(high, 26) + ta.lowest(low, 26)) / 2

spanA = plot((tenkan + kijun) / 2, "Span A", color.bull, offset=26)
spanB = plot((ta.highest(high, 52) + ta.lowest(low, 52)) / 2, "Span B",
             color.sell, offset=26)
fill(spanA, spanB, color.bull, color.sell, opacity=16)

plot(close, "Chikou", color.bull, offset=-26)

Ichimoku in the terminal is written exactly like that — not an example of how it could be done, but the very script the indicator is drawn by.

Colours

A colour is named by its role, not by its code: color.bull, color.sell, color.text, color.soft, color.accent, color.grid. An indicator then reads the same in the light theme and in the dark one. When an exact colour is needed — color.rgb(41, 98, 255).

What the language does not have, and will not

Loops, user-defined functions, recursion, access to files, the network, the machine clock, random numbers, your account or your orders. An indicator is a formula over candles; the terminal does everything else.

The compatibility promise

A script with //@version=1 must compute the same thing a year from now. New capability arrives as a new language version; old versions keep working. That rule outweighs any elegant rewrite.