Units and literals
How to write durations, times of day, exact instants, percentages and colours, what each one is as a number, and how to size a move in pips and ticks.
Numbers in a script often mean something: eight hours, half a percent, a time of day, a pip. Cuprel lets you write these directly. Each one is an ordinary number underneath, so you can add, subtract and compare it. What it is a number of is on this page.
Durations#
A whole number followed by a unit is a duration: 90s, 15m, 8h, 3d, 2w. A duration is a number of milliseconds, the same unit as bar.time, the time of a bar.
indicator "Recent bars only"
edition = 1
display = price
input window: int = 8, name = "Hours", min = 1
let recent = bar.time > clock.now - window * 1h
plot(if recent then close else na, name = "Close, last hours only")
chart.background(if recent then color.fade(color.blue, 94) else na)| Written | Is |
|---|---|
90s | 90000 |
15m | 900000 |
8h | 28800000 |
1d | 86400000 |
2w | 1209600000 |
Durations add and compare like numbers: 2h + 30m is 9000000, and 8h / 15m is 32, the number of 15-minute bars in eight hours. Write one unit at a time: 1h30m is an error, write 90m.
A time of day#
08:30 is a time of day, written hours and minutes. It is the number of milliseconds since midnight, and its main use is with a time zone, in session and clock.reached:
indicator "Open of the New York session"
edition = 1
display = price
let past_open = clock.reached(09:30 @ "America/New_York")
chart.background(if past_open then color.fade(color.green, 94) else na, name = "After the open")The zone follows @ and is a text. clock.reached(time @ zone) is true on the first bar of each date whose close is at or after that time in that zone. Trading day and sessions has the rest.
An exact moment#
An instant begins with @: @2026-09-17T07:10Z (the Z means UTC), @2026-09-17T07:10+03:30 (an offset), or @2026-09-17 07:10[Asia/Tehran] (a named zone). It is a number of milliseconds since 1970 in UTC, the same unit as bar.time.
indicator "Since a date"
edition = 1
display = price
let start = @2026-09-17 07:10[Asia/Tehran]
chart.background(
if bar.time >= start then color.fade(color.orange, 92) else na,
name = "After the start",
)
plot(close)An instant must say where it is. The same text without a zone would be a different moment on every machine, so it is refused:
indicator "An instant without a zone"
edition = 1
let start = @2026-09-17 07:10
plot(close)clock.timestamp("2026-09-17T07:10:00Z") turns a text into the same kind of number. The text must carry its zone, for the same reason; clock.timestamp("2026-09-17 07:10") is the error E-TS-ZONE.
Percentages#
0.5% is the number 0.005. Use it where you mean a share:
indicator "Band of half a percent"
edition = 1
display = price
let average = tech.sma(close, 20)
plot(average * (1 + 0.5%), name = "Upper", color = color.red)
plot(average * (1 - 0.5%), name = "Lower", color = color.green)Colours#
#rrggbb and #rrggbbaa are colours; see Values and types.
Pips and ticks#
A price move means different things on different symbols. Edition 1 gives you the contract's own figures and leaves the arithmetic to you:
| Name | Is |
|---|---|
symbol.tick | the smallest price step, a tick |
symbol.pip | the size of a pip in price units |
symbol.point_value | the money one whole unit of price makes for one lot |
indicator "A stop ten pips away"
edition = 1
display = price
input pips_away: float = 10, name = "Pips", min = 1
let stop_distance = pips_away * symbol.pip
plot(close - stop_distance, name = "Stop below the close", color = color.red)indicator "A helper that is not available"
edition = 1
plot(close - pips(10))A number that carries its unit with it (a value that remembers it is ticks or pips) is planned for a later edition. In edition 1 a duration is just a number of milliseconds and a percentage is just a fraction.
See also: Trading day and sessions, Your first strategy, Text and number formatting.