

Building Custom Session Highlighter in Pine Script Guide
Table of Contents
- Introduction
- What Is Building Custom Session Highlighter
- Why Building Custom Session Highlighter Matters for Traders and Investors
- Core Concepts
- Step‑by‑Step Guide
- Practical Tips for Better Results
- Common Mistakes to Avoid
- Frequently Asked Questions
- Conclusion
Introduction
When the London session opened on Tuesday, EUR/USD surged 15 pips in the first five minutes while Nasdaq‑100 futures (NQ) slipped on thin Asian liquidity. Traders whose charts displayed the exact session window reacted instantly; those who relied on a generic “9 am–4 pm” box missed the move and saw a stop‑loss triggered. The gap is not a mystery of market dynamics; it is the absence of a precise visual cue that matches the session you trade.
If you have ever drawn a static time‑of‑day rectangle on a chart only to watch it drift an hour when daylight‑saving time changes, you know how quickly a well‑timed scalping entry can become a loss. The mis‑alignment erodes the edge that comes from trading the first minutes of a session, when order flow is most concentrated.
The following guide shows how to eliminate that friction by building a custom session highlighter in Pine Script v5. You will receive a full code walk‑through, two live‑trading illustrations, and a checklist that keeps the indicator reliable across time‑zone shifts, holiday calendars, and changing market regimes.
What Is Building Custom Session Highlighter
A session highlighter is a visual overlay that shades the chart background—or draws a line—during a predefined market session such as London, New York, or the Asian overlap. “Building custom” means you write the logic yourself instead of using TradingView’s built‑in session overlay. The advantage is full control over time‑zone conversion, daylight‑saving adjustments, and dynamic color changes that react to price action.
For example, a trader may program the script to paint the background green from 08:00 GMT to 16:00 GMT for the London session on EUR/USD. When price breaks the session’s high, the script automatically switches the shade to amber, providing an at‑a‑glance breakout signal without scanning the price chart.
Why Building Custom Session Highlighter Matters for Traders and Investors
Professional desks at the CFTC‑regulated CME schedule algorithmic orders around session openings because liquidity spikes reduce slippage. Retail traders on the S&P 500, Nasdaq, or major forex pairs experience the same dynamics, yet they often lack a precise visual cue.
Ignoring session boundaries can produce two common pitfalls:
* Entering a breakout trade during the low‑liquidity Asian lull, where spreads widen and execution risk rises.
* Missing the first 10–20 pips of the London volatility burst, a chunk of a day‑trade’s profit target that often decides whether the trade ends in profit or loss.
A custom highlighter aligns your chart with the exact market hours you intend to trade, making it easier to filter signals, set time‑based exits, and backtest strategies that depend on session‑specific behavior.
Session Range Detection with the session() Function
The session() function returns a Boolean series that is true when the current bar falls inside the specified session string. The string follows the pattern "HH:MM-HH:MM:timezone".
Consider a day‑trader on NQ futures who wants to avoid the Asian session (02:00–09:00 EST). By defining
inAsian = session("0200-0900:America/New_York")
the script can suppress entry signals during those bars, reducing exposure to thin order books and widening bid‑ask spreads. The Boolean filter works on any timeframe, from 1‑minute scalps to 30‑minute swing bars.
Timezone Conversion and Daylight‑Saving Handling
Markets operate in local time, but your chart may be set to UTC or to your broker’s server time. Pine Script v5 offers the timestamp() function, which accepts a time‑zone identifier and automatically adjusts for daylight‑saving transitions.
A London‑based trader following EUR/USD on a chart set to UTC can convert the session start to UTC with
start = timestamp("Europe/London", year, month, day, 8, 0)
The highlighter then stays accurate whether the UK is on GMT or BST, eliminating the notorious “one‑hour drift” that breaks built‑in overlays each spring.
Dynamic Color Blending Based on Session Activity
Static shading only tells you that a session is active. Adding a dynamic color that reacts to price action—such as turning from green to red when price breaches the session low—delivers an immediate visual cue.
During the London session on EUR/USD, the script can track the session’s high and low. If price falls below the low, the background changes from green to red, alerting the trader to a potential reversal without manually scanning the chart. The color blending uses color.new(baseColor, transp), where transp is adjusted based on volatility measured by the Average True Range (ATR) indicator.
Step‑by‑Step Guide
## Step 1 — Define Session Parameters and Timezone
Begin by declaring the session’s start and end times in the market’s local zone. Provide input fields so you can switch between London, New York, or Asian sessions without editing code.
indicator("Custom Session Highlighter", overlay=true)
sessionChoice = input.string("London", "Session", options=["London","NewYork","Asian"])
tz = input.string("Europe/London", "Timezone")
startTime = sessionChoice == "London" ? "0800" :
sessionChoice == "NewYork" ? "1300" : "0000"
endTime = sessionChoice == "London" ? "1600" :
sessionChoice == "NewYork" ? "2100" : "0900"
The dropdown lets you re‑target any major session on the fly.
indicator("Custom Session Highlighter", overlay=true)
sessionChoice = input.string("London", "Session", options=["London","NewYork","Asian"])
tz = input.string("Europe/London", "Timezone")
startTime = sessionChoice == "London" ? "0800" :
sessionChoice == "NewYork" ? "1300" : "0000"
endTime = sessionChoice == "London" ? "1600" :
sessionChoice == "NewYork" ? "2100" : "0900"
Step 2 — Create the Boolean Session Filter
Combine the session() function with the parameters you just defined. The filter evaluates to true for every bar that belongs to the chosen session, even when daylight‑saving changes occur.
inSession = session(startTime + "-" + endTime + ":" + tz)
Because session() evaluates on a per‑bar basis, the filter works on both 1‑minute intraday charts and higher‑timeframe candles such as 30‑minute or daily.
Step 3 — Capture Session High and Low Dynamically
To enable dynamic color blending, you need the session’s high and low as they evolve. Reset the values at the start of each session and update them on every new bar.
var float sessHigh = na
var float sessLow = na
if not inSession[1] and inSession
sessHigh := high
sessLow := low
else if inSession
sessHigh := math.max(sessHigh, high)
sessLow := math.min(sessLow, low)
The var keyword preserves the values across bars, while the conditional block guarantees a fresh start at each session’s opening.
Step 4 — Apply Dynamic Color Logic
Choose base colors for “normal” session time and “breakout” conditions. Blend the colors with transparency that reflects the current ATR, a proxy for volatility.
atrVal = ta.atr(14)
baseColor = color.new(color.green, 85)
breakColor = color.new(color.red, 85)
sessionColor = inSession ?
(close > sessHigh ? breakColor : baseColor) :
na
bgcolor(sessionColor)
The example shades the background green during a quiet session and switches to red once price breaches the session high, providing a clear visual breakout cue.
Step 5 — Integrate a Simple Entry Rule (Optional)
If you wish to turn the highlighter into a strategy, add a condition that triggers only after a breakout.
longCondition = inSession and close > sessHigh and ta.crossover(ta.rsi(close, 14), 50)
if longCondition
strategy.entry("Long", strategy.long)
The rule requires price to break the session high and the 14‑period RSI to cross above 50, ensuring you trade with the session’s momentum.
Step 6 — Backtest Across Multiple Timeframes
Pine Script’s request.security() function lets you fetch higher‑resolution data while staying on a lower‑timeframe chart. Use it to verify that your session filter behaves consistently on 1‑minute versus 15‑minute charts.
high1 = request.security(syminfo.tickerid, "1", high)
low1 = request.security(syminfo.tickerid, "1", low)
Compare high1 and low1 against the session’s high/low calculated on the current chart to spot any slippage caused by bar‑closing mismatches.
Step 7 — Publish and Test on Real Data
Save the script and add it to a live chart of EUR/USD (FXCM) or NQ futures (CME). Observe the background shading during the next London or Asian session. Verify that the color change aligns with the actual price breaching the session low. Adjust the transparency or ATR multiplier if the shading is too faint during low‑volatility periods.
Practical Tips for Better Results
- Lock the timezone. Always set the
tzinput to the market’s official zone (e.g., “America/New_York” for NY futures). This prevents accidental drift when your chart’s exchange changes. - Add a volatility filter. Blend the background opacity with an ATR‑based rule so the shading stays visible during calm periods and becomes more pronounced when spreads widen.
- Prevent repainting. Use only confirmed bar data—avoid referencing future bars such as
close[1]inside the same bar—to keep backtests realistic. - Layer with volume. Plot a semi‑transparent volume histogram on top of the session shading; spikes often coincide with session openings, reinforcing the visual cue.
- Test daylight‑saving edges. Run the script through a calendar change (e.g., the last Sunday in March) to ensure the session start still aligns with the intended hour.
- Separate visual and strategic logic. Keep the highlighter as a visual aid; embed entry logic only if you are comfortable managing the added complexity.
- Cache session values. Use
varfor high/low storage to minimize recalculation overhead on high‑frequency charts (1‑minute or tick).Common Mistakes to Avoid
- Hard‑coding UTC offsets. Offsets break when daylight‑saving shifts occur, causing the overlay to drift.
- Relying on
timeinstead ofsession(). Thetimevariable does not respect market holidays, leading to false positives on non‑trading days. - Applying the highlighter on a daily chart. Session shading loses meaning when each bar already spans the whole session.
- Using
bgcolorwith full opacity. Full opacity overwrites price candles, making it hard to read chart patterns. - Neglecting to reset session high/low. Failing to clear variables at session start causes carry‑over from the previous day, distorting breakout signals.
How to create a session highlighter in Pine Script?
Use the
session()function with a properly formatted time‑zone string, capture session highs and lows withvarvariables, and applybgcolor()to shade the background. The step‑by‑step guide above outlines the exact code.What is a session highlighter indicator used for?
It visually marks market sessions on a chart, helping traders align entries, exits, and risk management with periods of higher liquidity or volatility, such as the London open or the New York close.
Why use custom session highlighting instead of built‑in sessions?
Custom code handles daylight‑saving changes, lets you blend colors based on price action, and works across any time zone you specify. Built‑in overlays often lag by an hour during DST transitions and lack dynamic coloring.
When should I apply a session highlighter to my strategy?
Apply it when your edge depends on session‑specific behavior—scalping the first 15 minutes of the London session, avoiding low‑liquidity Asian hours, or timing news releases that occur at a known market open.
Can I backtest a session highlighter with multiple timeframes?
Yes. Use
request.security()to fetch higher‑resolution data while testing on a lower‑timeframe chart. Verify that the session filter matches across resolutions to avoid look‑ahead bias.Is session highlighting compatible with Pine Script v5?
All functions used—
session(),timestamp(),bgcolor(), andrequest.security()—are native to v5, making the indicator fully compatible.Conclusion
A well‑crafted session highlighter turns raw market hours into an actionable visual layer, reducing missed opportunities and protecting against low‑liquidity traps. The single most important lesson is to let the script handle time‑zone conversion and daylight‑saving adjustments automatically; manual offsets are the source of most alignment errors.
Your next step: copy the code from the guide, apply it to a EUR/USD chart, and watch the background turn green at the London open. Tweak the color logic to suit your own volatility thresholds, then backtest a simple breakout strategy to quantify any edge.
Remember, no indicator guarantees profit. Use the highlighter as a timing aid, pair it with solid risk management, and stay aware that market conditions can shift quickly. Trade responsibly.
—
This article is for educational purposes only and does not constitute investment advice. Trading and investing carry risk of loss; never invest more than you can afford to lose.
Last reviewed August 2026
Last reviewed: August 2026




















































