Lesson 9: Sessions and a small table
Mark a trading session, keep a value that starts again each day, show the numbers in a table, and handle bars that have no value yet.
Lesson 9 of 18. Markets have hours. This lesson names a session, measures it, restarts a counter every trading day, prints the result in a table in the corner of the chart, and deals with the empty values that every indicator has on its first bars.
A session#
A session is a daily window of time in a time zone. You declare it once at the top of the file, and then read it through its members.
indicator "London range"
edition = 1
display = price
session london = 08:00 .. 16:30 @ "Europe/London"
plot(london.high, name = "London high", color = color.green)
plot(london.low, name = "London low", color = color.red)
chart.background(if london.active then color.fade(color.blue, 92) else na, name = "London open")london.activeis true on the bars that open inside the session.london.highandlondon.loware the highest high and lowest low of the latest session. They run while the session is open and keep their value after it ends, until the next one starts.- The time zone is written in the script. Winter and summer time follow the zone, so the session stays at 08:00 London time all year.
A value that starts again each day#
state keeps a value from bar to bar. state day starts it again at the beginning of each trading day, which is the symbol's own day, not midnight.
indicator "Change since the day opened"
edition = 1
state day day_open = close
plot(close - day_open, name = "Change today", style = histogram)state day day_open = close takes the close of the first bar of the day and keeps it until the next day starts. A plain state would keep the first close of the whole chart. Trading day and sessions says where a trading day starts.
A small table#
A table is drawn once, on the last bar, in a corner of the chart.
indicator "Range table"
edition = 1
display = price
session asia = 00:00 .. 08:00 @ "Asia/Tokyo"
if bar.is_last
let t = table.new(top_right, 2, 3)
table.cell(t, 0, 0, "Asia high")
table.cell(t, 1, 0, f"{asia.high:price}")
table.cell(t, 0, 1, "Asia low")
table.cell(t, 1, 1, f"{asia.low:price}")
table.cell(t, 0, 2, "Range")
table.cell(t, 1, 2, f"{asia.high - asia.low:price}")
plot(close)table.new(position, columns, rows) makes the table; table.cell(table, column, row, text) writes a cell. Columns and rows are counted from 0. bar.is_last is true only on the last bar, so the table is built once instead of on every bar.
Bars with no value#
A moving average of 20 bars has nothing to say on the first 19 bars. Those bars hold na, which means "no value". A plot leaves a gap where the value is na.
Three tools deal with it:
is_na(x)is true whenxisna.- In an f-text,
{x:.2f?'n/a'}writes a text in place of a number that isna(the table below uses it). a ?? bisa, orbwhenaisna.
indicator "Distance from average"
edition = 1
input length: int = 50, name = "Length", min = 2
let average = tech.sma(close, length)
let distance = close - average
plot(distance ?? 0, name = "Distance (0 until there is an average)")
if bar.is_last
let t = table.new(top_right, 2, 1)
table.cell(t, 0, 0, "Distance")
table.cell(t, 1, 0, f"{distance:.2f?'n/a'}")In the table, {distance:.2f?'n/a'} writes the number with two decimals, or the text n/a when there is none.
indicator "Wrong na test"
edition = 1
let average = tech.sma(close, 20)
plot(if average == na then 0 else average)Try changing#
- In "London range", follow New York instead:
session new_york = 09:30 .. 16:00 @ "America/New_York", and writenew_york.high,new_york.lowandnew_york.activein the three lines below it. - In "Change since the day opened", write
state day_open = close(withoutday): the value now counts from the first bar of the whole chart. - In "Range table", move the table with
table.new(bottom_left, 2, 4)and add a fourth row:table.cell(t, 0, 3, "Close")andtable.cell(t, 1, 3, f"{close:price}"). - In "Distance from average", plot
distanceinstead ofdistance ?? 0: the line now starts with a gap on the first bars.
Checkpoint#
- You can declare a session with its hours and time zone and read
.active,.highand.low. - You can keep a value that starts again every trading day with
state day. - You can build a table once, on the last bar, and write numbers into its cells.
- You can handle
nawithis_na,??and the f-text fallback.
See also: Trading day and sessions, Tables, na, errors and arithmetic.