Session Vlevel (trading sessions)
Session Vlevel is Vlevel's own indicator: it marks the Sydney, Tokyo, London and New York sessions in each city's local time, with each session's high and low, on the chart.
What it is
Forex and gold trade 24 hours a day, but they don't behave the same all day. The Asian session is usually quiet, the London open brings movement, and the London–New York overlap is the busiest time. Session Vlevel marks these hours in separate colours and handles each city's daylight-saving changes itself.
How it's calculated
- Each session is defined by its city's official hours: Sydney, Tokyo, London and New York.
- For each session, the highest and lowest prices during it are drawn as a box on the chart.
- Each city's daylight-saving time is applied separately, so sessions always match the real market hours.
How traders read it
- A break of the Asian session's high or low early in London is a common daily pattern.
- The London–New York overlap is usually the most volatile time of day.
- To filter trading hours: many strategies only have an edge in one session.
Settings
You can switch each session on or off and change its colour. It shows best on intraday timeframes (1 minute to 1 hour).
Where it misleads
- Sessions matter for 24/5 markets like forex and gold; in crypto, which also trades at weekends, they matter less.
- Public holidays in a country change how its session behaves.
Its Pine Script on Vlevel
This is the script the chart runs. In the chart's indicators window you can open it, change it and save your own copy.
Session Vlevel · Pine Script v6
//@version=6
// Session Vlevel: the New York, London, Tokyo and Sydney sessions, each read in its own city's
// local time, so the boxes follow daylight-saving changes by themselves.
indicator("Session Vlevel", overlay = true, max_boxes_count = 500, max_labels_count = 500, max_lines_count = 500)
nyOn = input.bool(true, "New York", group = "Sessions", inline = "ny")
nyHours = input.session("0800-1700", "", group = "Sessions", inline = "ny")
nyColor = input.color(#ff5d00, "", group = "Sessions", inline = "ny")
ldOn = input.bool(true, "London", group = "Sessions", inline = "ld")
ldHours = input.session("0700-1600", "", group = "Sessions", inline = "ld")
ldColor = input.color(#2157f3, "", group = "Sessions", inline = "ld")
tkOn = input.bool(true, "Tokyo", group = "Sessions", inline = "tk")
tkHours = input.session("0900-1800", "", group = "Sessions", inline = "tk")
tkColor = input.color(#e91e63, "", group = "Sessions", inline = "tk")
syOn = input.bool(true, "Sydney", group = "Sessions", inline = "sy")
syHours = input.session("0800-1700", "", group = "Sessions", inline = "sy")
syColor = input.color(#ffeb3b, "", group = "Sessions", inline = "sy")
shade = input.int(90, "Box transparency", minval = 0, maxval = 100, group = "Style", display = display.none)
showNames = input.bool(true, "Session names", group = "Style")
showMid = input.bool(false, "Middle of the range", group = "Style")
showDays = input.bool(true, "Day dividers", group = "Style")
// One session: while it runs, a box over its high and low with its name above the middle.
session(bool on, string hours, string zone, string name, color c) =>
var box frame = na
var label tag = na
var line mid = na
var float hi = na
var float lo = na
var int first = 0
var bool was = false
active = on and timeframe.isintraday and not na(time(timeframe.period, hours, zone))
// A gap of hours (a weekend or a holiday) ends the session even if both sides fall inside it.
reopened = bar_index > 0 and time - time[1] > 4 * 3600000
if active and (not was or reopened)
first := bar_index
hi := high
lo := low
frame := box.new(bar_index, hi, bar_index, lo, border_color = c, border_style = line.style_dotted, bgcolor = color.new(c, shade))
tag := showNames ? label.new(bar_index, hi, name, style = label.style_label_down, color = #00000000, textcolor = c, size = size.tiny) : na
mid := showMid ? line.new(bar_index, (hi + lo) / 2, bar_index, (hi + lo) / 2, color = c, style = line.style_dashed) : na
else if active
hi := math.max(hi, high)
lo := math.min(lo, low)
box.set_top(frame, hi)
box.set_rightbottom(frame, bar_index, lo)
label.set_xy(tag, math.round((first + bar_index) / 2), hi)
line.set_xy1(mid, first, (hi + lo) / 2)
line.set_xy2(mid, bar_index, (hi + lo) / 2)
was := active
active
session(nyOn, nyHours, "America/New_York", "New York", nyColor)
session(ldOn, ldHours, "Europe/London", "London", ldColor)
session(tkOn, tkHours, "Asia/Tokyo", "Tokyo", tkColor)
session(syOn, syHours, "Australia/Sydney", "Sydney", syColor)
// A dashed line where each new day starts.
if showDays and timeframe.isintraday and dayofweek != dayofweek[1]
line.new(bar_index, low, bar_index, high, extend = extend.both, color = color.new(color.gray, 55), style = line.style_dashed)Indicators describe past prices; none predicts the future. For education, not investment advice.