TradingCharts

Objects

A user-defined type (UDT) groups related values under one name. UDTs are the structured-data primitive of ChartScript — any collection of fields that belong together should be a UDT…

Declaring a type

type Pivot
    int   bar
    float price
    bool  isHigh
  • Fields are listed indented, one per line.
  • Each field has an explicit type keyword (int, float, bool, string, color, another UDT, an array/map/matrix type, or a reference type like line).
  • A field can declare a default: float price = na.

Field defaults make .new() arguments optional:

type ZoneBox
    int   left   = na
    int   right  = na
    float top    = na
    float bottom = na
    color borderColor = color.gray
    color fillColor   = color.new(color.gray, 90)

Creating an instance

p = Pivot.new(bar_index, high, true)
log.info("pivot " + (p.isHigh ? "H" : "L") + " @ " + str.tostring(p.price))
  • TypeName.new(…) is a constructor; arguments are positional, in field order, or named.
  • Field-less construction is allowed: p = Pivot.new() leaves every field at its default (na for primitives, "" for strings, white for colors).

Reading and writing fields

p.price           // read
p.price := 100.5  // write

A field write uses :=. Reading is a bare dot-access.

Nested types

Types can contain other UDTs:

type Trendline
    Pivot start
    Pivot end
    color col

Field assignment on a nested value chains:

t.start.price := high

Methods on UDTs

See Methods — a method whose this is a UDT reads like native syntax:

method label(Pivot this) =>
    this.isHigh ? "H" : "L"

log.info(Pivot.new(0, 100.0, true).label())   // "H"

Reference semantics

UDTs are reference types: assigning or passing one does not copy it. Two names bound to the same instance observe each other's writes:

a = Pivot.new(0, 100, true)
b = a
b.price := 200
log.info(str.tostring(a.price))  // 200

Create a copy with a fresh .new() call (or write a method copy() on the type).

Arrays of UDTs

A common pattern is an array of UDT instances for history:

var array<Pivot> pivots = array.new<Pivot>()

p = ta.pivothigh(5, 5)
if not na(p)
    pivots.push(Pivot.new(bar_index[5], p, true))

Walk the array with for … in and dot-access to field read:

for piv in pivots
    label.new(piv.bar, piv.price, piv.isHigh ? "H" : "L")

Exported types

Libraries can export types for other scripts to use:

//@version=1
library("PivotTypes")

export type Pivot
    int   bar
    float price
    bool  isHigh

export method label(Pivot this) =>
    this.isHigh ? "H" : "L"

A library must export a UDT if any exported function/method accepts or returns a reference of that type.

See also