Builtins: time and sessions

Time functions read UTC unless you name a zone. Called without an argument they use the current bar start. An absent timestamp returns nan.

SignatureReturns
time.year([timestamp: float, zone]) -> intFour digit year
time.month([timestamp: float, zone]) -> intMonth, 1 through 12
time.day([timestamp: float, zone]) -> intDay of month, 1 through 31
time.hour([timestamp: float, zone]) -> intHour, 0 through 23
time.minute([timestamp: float, zone]) -> intMinute, 0 through 59
time.second([timestamp: float, zone]) -> intSecond, 0 through 59
time.weekday([timestamp: float, zone]) -> intWeekday, Sunday 0 through Saturday 6
session.in(window: string [, zone]) -> boolWhether the bar starts inside the window
session.open(window: string, zone) -> floatThe opening price of the current session, nan outside it
session.adr(length: int, window: string, zone) -> floatAverage high minus low of the last length complete sessions, nan outside the session
  • A window is written "HHMM-HHMM" with hours 00 to 23 and minutes 00 to 59, and excludes its closing instant.
  • A zone is a whole number of minutes east of UTC, so New York in winter is -300, or one of the strings "UTC", "America/New_York" and "Europe/Prague". Any other name is rejected, so daylight saving is never guessed. New York applies the US rules in force since 2007 and Prague the EU rules in force since 1996; a bar older than that reads as outside the session, and a time.* call answers nan there, rather than being answered with the wrong rule.
  • The time.* functions also read the exchange clocks: "America/Chicago" for CME, "Europe/London", "Asia/Tokyo", "Asia/Hong_Kong" and "Australia/Sydney", each with its own daylight saving rules. Chicago follows the US rules since 2007, London the EU rules since 1996 and Sydney the New South Wales rules since 2008; Tokyo and Hong Kong have no daylight saving. session.in, session.open and session.adr keep the three zones above.
  • time.hour(time, "America/New_York") is the New York hour of the bar. To read a time part of an earlier bar, store it in a series first, such as let ny_day: float = time.day(time, "America/New_York"), and read ny_day[1].
  • A Chicago session is the New York session one hour later all year, because both follow the US daylight saving dates: the CME day session 08:30 to 15:00 Chicago is session.in("0930-1600", "America/New_York"). A window on another exchange clock is built from that clock's hour and minute, as the example below does for London.
  • session.in accepts an overnight window that wraps midnight. session.open and session.adr require a daytime window that starts before it ends.
  • session.adr takes a length from 1 through 252, skips the still forming session, and skips a session that started late or had a gap. It stays nan until enough complete sessions exist.
  • Call session.open and session.adr at the top level so they observe every bar.
  • For futures, "America/New_York" is almost always what you want: it follows daylight saving on its own.
The cash session, with daylight saving handled
let window: string = "0930-1600"
let cash: bool = session.in(window, "America/New_York")
let anchor: float = session.open(window, "America/New_York")
let adr: float = session.adr(5, window, "America/New_York")
plot.line(anchor + adr, "#22C55E", 2, "solid")
plot.line(anchor - adr, "#EF4444", 2, "solid")
The London session on the London clock, and the CME trading day
let lon_h: float = time.hour(time, "Europe/London")
let lon_min: float = lon_h * 60 + time.minute(time, "Europe/London")
let in_london: bool = lon_min >= 480 && lon_min < 990
plot.candle_color(in_london, "#3B82F6", 0.35)
let cme_day: float = time.day(time, "America/Chicago")
let cme_hour: float = time.hour(time, "America/Chicago")
plot.vline(cme_hour == 17 && cme_hour[1] != 17, "#6B7280", 1, "dotted")
plot.label(str.concat("CME day ", format.fixed(cme_day, 0)), "#E5E7EB")

A fixed number of minutes is the other way to say it and is constant all year. Expose it as an input when you want the trader to point the tool at their own session.

The same window on a user settable shift
let shift: int = input.int(-300, "shiftMinutes", "Minutes from UTC", -840, 840, 15)
let inside: bool = session.in("0930-1600", shift)
plot.candle_color(inside, "#1F2937", 0.5)

Every layer of the market, Orderflow to optionflow, on one chart.

Institutional grade Orderflow data with backtesting and journaling built in. Join the waitlist for early access.

Get Access