Skip to content
ChartDeck ChartScript docs Account Open the terminal

Sessions

Session strings, time() with a session, the session.* values, and what a trading session means on 24/7 crypto markets.

Coin markets never close. There is no opening bell, no pre-market and no weekend gap, so ChartDeck treats every market as trading around the clock and calls the UTC day its session. The traditional sessions still matter to crypto traders, though: liquidity and volatility change when Asia, London and New York are at their desks. ChartScript lets you describe any window of the day as a session string and test whether a bar falls inside it.

#Session strings

A session string is "HHMM-HHMM", optionally followed by : and the days it applies to:

StringMeaning
"0800-1600"from 08:00 up to (not including) 16:00, every day
"2200-0600"an overnight window: from 22:00 to 06:00 the next morning
"0000-0000"the whole day
"1330-2000:23456"13:30 to 20:00, Monday to Friday only

Days are digits from 1 (Sunday) to 7 (Saturday), the same numbering as dayofweek. "23456" is Monday to Friday; "17" is the weekend.

The start is inclusive and the end is exclusive, so "0800-1600" contains a bar opening at 15:59 but not one opening at 16:00. Times are in UTC unless you give a time zone (below).

#Testing a bar: time() with a session

time(timeframe, session, timezone) returns the bar's time when the bar is inside the session, and na when it is outside. So !na(time(…)) is the usual "is this bar in the session?" test:

ChartScriptFragmentOpen in editor
const inLondon = !na(time("", "0800-1630", "Europe/London"))
bgcolor(inLondon ? color.new(color.accent, 90) : na, { title: "London session" })
  • timeframe: "" means the chart's timeframe. Give another one ("1D") and the result is the start of that timeframe's bar instead of the chart bar's time.
  • session: the session string. "" means no session filter.
  • timezone: the zone the session's clock times are read in. Default "UTC". An IANA name such as "America/New_York" follows daylight saving, so a New York session stays at 09:30-16:00 local time all year while its UTC hours shift.

The test looks at the open time of each chart bar. On a 4-hour chart a bar opening at 12:00 counts as inside "1330-2000" only if it opens inside the window, which it does not. Sessions are most useful on charts of an hour or less.

time_close takes the same arguments and returns the bar's close time, or na outside the session.

#The session namespace on 24/7 markets

The session values exist so that scripts written for exchange-traded markets keep working. On coin markets their answers follow from "the session is the UTC day":

NameOn ChartDeck
session.ismarketalways true
session.ispremarket, session.ispostmarketalways false
session.isfirstbar (and _regular)true on the first bar of each UTC day
session.islastbar (and _regular)true on the last bar of each UTC day
session.regular, session.extendedaccepted; they mean the same thing here

session.isfirstbar is a quick way to reset something every day:

ChartScriptFragmentOpen in editor
state dayHigh: float = na
dayHigh = session.isfirstbar ? high : math.max(dayHigh, high)
plot(dayHigh, "High of the UTC day", color.muted, { style: plot.style_stepline })

#Session settings for the user

input.session gives the user a session string to edit, with optional choices. Combine it with a time-zone choice so people can work in their own clock:

ChartScriptFragmentOpen in editor
const sess = input.session(
    "0930-1600:23456",
    "Session",
    { options: ["0930-1600:23456", "0800-1630:23456", "0000-0800"] }
)
const tz = input.string(
    "America/New_York",
    "Time zone",
    { options: ["UTC", "America/New_York", "Europe/London", "Asia/Tokyo"] }
)
bgcolor(!na(time("", sess, tz)) ? color.new(color.accent, 92) : na, { title: "Session" })

#A whole example: session high and low

This indicator tracks the high and low of a chosen session, keeps them on the chart after the session ends, and marks the moment price breaks either one. The session high/low tutorial builds a similar script step by step.

ChartScriptOpen in editor
//@chartscript 1
indicator("Session range", { overlay: true })

const sess = input.session("1330-2000:23456", "Session (UTC unless a zone is set)")
const tz = input.string("UTC", "Time zone", { options: ["UTC", "America/New_York", "Europe/London", "Asia/Tokyo"] })
const showBreaks = input.bool(true, "Mark breaks of the range")

const inSess = !na(time("", sess, tz))
const started = inSess && !inSess[1]
const ended = !inSess && inSess[1]

state sHigh: float = na
state sLow: float = na
state done: bool = false

if (started) {
    sHigh = high
    sLow = low
    done = false
} else if (inSess) {
    sHigh = math.max(sHigh, high)
    sLow = math.min(sLow, low)
}
if (ended) {
    done = true
}

plot(sHigh, "Session high", color.up, { style: plot.style_linebr })
plot(sLow, "Session low", color.down, { style: plot.style_linebr })
bgcolor(inSess ? color.new(color.accent, 93) : na, { title: "In session" })

const brokeUp = done && ta.crossover(close, sHigh)
const brokeDown = done && ta.crossunder(close, sLow)
plotshape(showBreaks && brokeUp && barstate.isconfirmed, "Break up", shape.triangleup, location.belowbar, color.up)
plotshape(
    showBreaks && brokeDown && barstate.isconfirmed,
    "Break down",
    shape.triangledown,
    location.abovebar,
    color.down
)

The break markers use barstate.isconfirmed, so they appear only once a bar has closed beyond the level and never flicker on the live bar. Repainting explains why that matters.

The ChartScript documentation is in English for now; translations will follow.