ScriptingWriting Lipiconst, simple and series

const, simple and series

Every value carries two labels. Its data type says what it holds. Its form type says how often it can change.

You rarely write a form type. The interpreter settles one for every value, and the language gives you a single position in which to state one yourself.

The five form types

Five exist, ordered from narrowest to widest.

Form typeHow much the value can changeDo you write it?
literala value written into the source itselfno — it becomes const when you assign it to a name
constfixed when the script is compiledon a function parameter
inputcomes out of one of the input functionsno — the call produces it
simplefixed for the whole run of the scripton a function parameter
seriesmay differ on every baron a function parameter

Read the table downwards and each row is wider than the one above it.

A declaration takes no form type

A variable declaration is an optional persistence keyword, an optional data type, the name, =, and an expression. There is no slot for a form type. Put one there and the script stops parsing.

// None of these parse.
const float threshold = 0.5
simple int lookback = 14
series float average = (close + close[1]) / 2

The interpreter stops at the form type and reports “no viable alternative”. The keyword slot at the front of a declaration is for persistence — whether a value survives from one bar to the next — and it takes nothing else. The data type slot is optional: write the type, or leave it out.

indicator("Two-bar average", "avg2", true)

float average = (close + close[1]) / 2

plot(average)

The declaration says what average holds. It says nothing about how often the value changes, and it cannot.

A function parameter is where you write one

A parameter is an optional form type, a required data type, the name, and an optional default. Note which one is compulsory: the data type. The form type in front of it is not.

indicator("Bar range", "range", false)

def diff(series float x, series float y) => x - y

plot(diff(high, low))

Dropping series from both parameters is also accepted. Dropping float is not.

Reading the order

The five forms run narrowest to widest:

literalconstinputsimpleseries

A value is accepted where a wider form is expected. It is refused where a narrower one is expected. That rule is what the form types are for, and it is why an argument of the right data type can still be turned away.

Signatures are where you meet the rule. The declaration function takes const arguments throughout:

indicator(const string title, const string shorttitle, const bool overlay, const string format, const int precision) → void

So a script’s title has to be a constant. Nothing wider than const will do there.

An input is not a const

A value that came out of an input function carries the input form — you never write that form, the call produces it. input sits above const in the order, so such a value is refused wherever a const is required. Reach for an input to fill in a script’s title and you meet that refusal.

simple and series on the chart

What the chart is stays fixed while a script runs, so the instrument’s details and the interval are simple. What the market did changes from bar to bar, so the bar’s own values are series. That is the order in its everyday shape: a value read off a bar cannot stand in for a chart-level fact.

Ready to put this into practice?
Try GoCharting Premium
Unlock advanced orderflow, market profile, options desk, and real-time data — everything you just read about, live in your charts.
Upgrade