Session High Low Indicator for TradingView
Identify key liquidity pools and market turning points by plotting Asian, London, and New York session high and low levels. This Pine Script v6 indicator draws dynamic session boxes, historical boundary levels, and ATR expansion targets to frame intraday trades with precision.
Why Session Highs and Lows Matter
Global financial markets operate in continuous regional waves. The trading day begins in Asia (Tokyo/Sydney), flows into London (European open), and concludes in New York (US market hours). Each session leaves behind a distinct high and low price level representing the highest price buyers were willing to pay and the lowest price sellers accepted during those hours.
Because institutional algorithms and retail stop orders cluster around these session extremes, price frequently reacts strongly when testing them. A session high acts as key intraday resistance until broken; once swept, it often fuels rapid continuation or sharp mean reversion.
Asian Session
19:00 - 02:00 UTC. Low volatility consolidation range. Forms the initial liquidity boundaries that London traders target.
London Session
08:00 - 16:30 UTC. High volume surge. Often initiates the Judas Swing (sweeping Asian levels) before creating the true trend.
New York Session
13:30 - 20:00 UTC. Peak market liquidity where major economic news releases and equity market open volume drive expansion.
Pine Script v6 Source Code
Copy and paste this production-ready script into your TradingView Pine Editor. It supports session boxes, trackprice horizontal levels, ATR extensions, and breakout alerts.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// (c) Pineify
//@version=6
indicator(title="Session High Low Indicator [Pineify]", overlay=true, max_boxes_count=500, max_lines_count=500)
// ---------------- Inputs ----------------
string grp_asia = "Asian Session"
bool show_asia = input.bool(true, "Show Asian Session", group=grp_asia)
string asia_sess = input.session("1900-0200", "Session Hours (UTC)", group=grp_asia)
color asia_col = input.color(color.new(color.blue, 85), "Box Color", group=grp_asia)
color asia_line = input.color(color.blue, "Border Color", group=grp_asia)
string grp_lon = "London Session"
bool show_lon = input.bool(true, "Show London Session", group=grp_lon)
string lon_sess = input.session("0800-1630", "Session Hours (UTC)", group=grp_lon)
color lon_col = input.color(color.new(color.orange, 85), "Box Color", group=grp_lon)
color lon_line = input.color(color.orange, "Border Color", group=grp_lon)
string grp_ny = "New York Session"
bool show_ny = input.bool(true, "Show New York Session", group=grp_ny)
string ny_sess = input.session("1330-2000", "Session Hours (UTC)", group=grp_ny)
color ny_col = input.color(color.new(color.green, 85), "Box Color", group=grp_ny)
color ny_line = input.color(color.green, "Border Color", group=grp_ny)
string grp_atr = "ATR Target Extensions"
bool show_atr = input.bool(true, "Plot ATR Extensions", group=grp_atr)
float atr_mult = input.float(1.0, "ATR Multiplier", minval=0.1, step=0.1, group=grp_atr)
// ---------------- Session High/Low Function ----------------
f_calc_session(string sess_str, bool is_active) =>
in_session = not na(time(timeframe.period, sess_str, "UTC"))
is_start = in_session and not in_session[1]
var float s_high = na
var float s_low = na
var int s_start_bar = na
var box s_box = na
if is_start
s_high := high
s_low := low
s_start_bar := bar_index
if is_active and timeframe.isintraday
s_box := box.new(left=bar_index, top=high, right=bar_index, bottom=low,
border_color=color.gray, bgcolor=color.new(color.gray, 90))
else if in_session
s_high := math.max(nz(s_high, high), high)
s_low := math.min(nz(s_low, low), low)
if not na(s_box)
box.set_top(s_box, s_high)
box.set_bottom(s_box, s_low)
box.set_right(s_box, bar_index)
[s_high, s_low, in_session, is_start, s_box]
// ---------------- Calculations ----------------
[asia_h, asia_l, asia_in, asia_start, asia_b] = f_calc_session(asia_sess, show_asia)
[lon_h, lon_l, lon_in, lon_start, lon_b] = f_calc_session(lon_sess, show_lon)
[ny_h, ny_l, ny_in, ny_start, ny_b] = f_calc_session(ny_sess, show_ny)
// Apply styling to session boxes
if not na(asia_b) and show_asia
box.set_border_color(asia_b, asia_line)
box.set_bgcolor(asia_b, asia_col)
if not na(lon_b) and show_lon
box.set_border_color(lon_b, lon_line)
box.set_bgcolor(lon_b, lon_col)
if not na(ny_b) and show_ny
box.set_border_color(ny_b, ny_line)
box.set_bgcolor(ny_b, ny_col)
// Daily ATR for extension targets
daily_atr = request.security(syminfo.tickerid, "1D", ta.atr(14))
// ---------------- Plots ----------------
plot(timeframe.isintraday and show_asia ? asia_h : na, "Asian High", color=asia_line, style=plot.style_circles, offset=-9999, trackprice=true)
plot(timeframe.isintraday and show_asia ? asia_l : na, "Asian Low", color=asia_line, style=plot.style_circles, offset=-9999, trackprice=true)
plot(timeframe.isintraday and show_lon ? lon_h : na, "London High", color=lon_line, style=plot.style_circles, offset=-9999, trackprice=true)
plot(timeframe.isintraday and show_lon ? lon_l : na, "London Low", color=lon_line, style=plot.style_circles, offset=-9999, trackprice=true)
plot(timeframe.isintraday and show_ny ? ny_h : na, "NY High", color=ny_line, style=plot.style_circles, offset=-9999, trackprice=true)
plot(timeframe.isintraday and show_ny ? ny_l : na, "NY Low", color=ny_line, style=plot.style_circles, offset=-9999, trackprice=true)
plot(timeframe.isintraday and show_atr and not na(ny_h) ? ny_h + daily_atr * atr_mult : na, "NY High + ATR", color=color.gray, style=plot.style_circles, offset=-9999, trackprice=true)
plot(timeframe.isintraday and show_atr and not na(ny_l) ? ny_l - daily_atr * atr_mult : na, "NY Low - ATR", color=color.gray, style=plot.style_circles, offset=-9999, trackprice=true)
// ---------------- Alerts ----------------
alertcondition(ta.crossover(close, asia_h), "Asian High Breakout", "Price broke above Asian Session High")
alertcondition(ta.crossunder(close, asia_l), "Asian Low Breakdown", "Price broke below Asian Session Low")
alertcondition(ta.crossover(close, lon_h), "London High Breakout", "Price broke above London Session High")
alertcondition(ta.crossunder(close, lon_l), "London Low Breakdown", "Price broke below London Session Low")
| Parameter | Default | Purpose |
|---|---|---|
| Session Hours | UTC Timings | Configurable string (e.g., 1900-0200) matching your timezone requirements. |
| Box Color & Line | Blue / Orange / Green | Visual fill opacity and border color for the 3 distinct market sessions. |
| ATR Multiplier | 1.0 | Daily ATR(14) extension target levels plotted above the session high and below the session low. |
3 Practical Session Trading Strategies
1. Asian Range Breakout (London Open Strategy)
Identify the Asian session high and low range. When the London market opens (08:00 UTC), wait for a 5-minute candle to close completely outside the Asian boundary. Enter in the direction of the breakout with a stop loss inside the Asian range, targeting the +1 ATR extension level.
2. Session High/Low Liquidity Sweep (Judas Swing)
Price pierces the Asian high during early London hours, triggering buy stops, but fails to hold and closes back below the session high. This fakeout signals institutional selling. Enter short with a stop above the spike wick, targeting the opposite Asian session low.
3. NY Session Continuation at London High/Low
When London establishes a strong directional trend, the NY open often pulls back to retest the London high (in an uptrend) as support. Look for a bullish candlestick confirmation at the London high line to enter long with the daily momentum.
Automate Session Strategies in Pine Script
Want to combine session breakouts with EMA filters, trailing stops, or webhook alerts? Build it with Pineify AI in seconds.