Indicator · Pine Script v5 · On the chart

ICT Time Range

by vitahoang

This overlay indicator marks configurable trading sessions and higher-timeframe ranges on the price chart.

View on GitHub

GitHub stars5on the repository
Pine versionv5runs as is
Lines of code325
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update3 years ago29 Dec 2022

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

325 lines of Pine Script v5 from ict.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

ict.pine
//@version=5
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © VitaHoang
indicator('ICT Time Range', overlay=true, max_bars_back=500, max_labels_count=500, max_lines_count=500, max_boxes_count=500)

//––––––––––––––––––––CONSTANTS––––––––––––––––––––
LABEL_OFFSET_Y = 5000
_1M = 1000 * 60
_1H = 60 * _1M
_24H = 24 * _1H
TOOLTIP01 = "Enter your time zone's offset (+ or −), including a decimal fraction if needed."

//––––––––––––––––––––UTILITIES––––––––––––––––––––
print(txt) =>
    // Create label on the first bar.
    var lbl = label.new(bar_index, na, txt, xloc.bar_index, yloc.price, color(na), label.style_none, color.gray, size.large, text.align_left)
    // On next bars, update the label's x and y position, and the text it displays.
    label.set_xy(lbl, bar_index, ta.highest(10)[1])
    label.set_text(lbl, txt)


//––––––––––––––––––––INPUTS––––––––––––––––––––

var grps = 'Main Settings'
showSession = input.bool(defval = true, title = "Show Session?", group = grps) 
showLable = input.bool(defval = true, title = "Show Lable?", group = grps) 
hoursOffset = input.int(0, "Timezone offset (hrs)", minval = -12, maxval = 14, step = 1, tooltip = TOOLTIP01)
minutesOffset = input.int(0, "Timezone offset (mins)", minval = 0, maxval = 30, step = 30, tooltip = TOOLTIP01)
linesWidth = input.int(1, title='Lines Width', minval=1, maxval=4, group=grps)
_labelSize = input.string("Small", title='Label Size', options=['Auto', 'Tiny', 'Small', 'Normal', 'Huge'], group=grps)
labelSize = _labelSize == "auto" ? size.auto : _labelSize == "Tiny" ? size.tiny : _labelSize == "Small" ? size.small : _labelSize == "Normal" ? size.normal : size.huge

int msOffset = hoursOffset * _1H + minutesOffset * _1M
string utcOffset = if hoursOffset < 0
    "UTC-" + (hoursOffset > -10 ? "0" : na) + str.tostring(0-hoursOffset) + ":" + (minutesOffset == 0 ? "00" : "30")
else
    "UTC+" + (hoursOffset < 10 ? "0" : na) + str.tostring(hoursOffset) + ":" + (minutesOffset == 0 ? "00" : "30")

//––––––––––––––––––––HTF RANGE––––––––––––––––––––
// Inputs
var GRPW = 'HTF Range Settings'
showHtf = input.bool(true, title='Show HTF Range?', inline='1', group=GRPW)
showHtfWeek = input.bool(true, title='Show Weekly Range?', inline='2', group=GRPW)
colorHtfWeek = input.color(color.orange, title='', inline='2', group=GRPW)
showHtfDay = input.bool(true, title='Show Daily Range?', inline='3', group=GRPW)
colorHtfDay = input.color(color.gray, title='', inline='3', group=GRPW)



string tfw = input.timeframe("W", "Timeframe")
string tfd = input.timeframe("D", "Timeframe")


// Functions

drawWeekHline(_price, _color) =>
    line.new(bar_index - 1, _price, bar_index, _price, xloc.bar_index, extend.none, _color, line.style_dotted, 1)


drawHTF (tf, showTf, _color)=> 
    var _H = float(na)
    var _L = float(na)
    var _O = float(na)
    var line weekH = na
    var line weekL = na
    var line weekO = na
    // Detect changes in timeframe.
    bool newTF = ta.change(time(tf))
    if showTf
        if newTF
            _H := high
            _L := low
            _O := open
            weekH := drawWeekHline(high, _color)
            weekL := drawWeekHline(low, _color)
            weekO := drawWeekHline(open, _color)

            // Remove extend of the old range
            line.set_extend(weekH[1], extend.none)
            line.set_extend(weekL[1], extend.none)
            line.set_extend(weekO[1], extend.none)
            int(na)

        // Extend line of the current range
        if newTF[1]
            line.set_extend(weekH, extend.right)
            line.set_extend(weekL, extend.right)
            line.set_extend(weekO, extend.right)
            int(na)

        else
            if high > _H
                _H := high
                int(na)
            if low < _L
                _L := low
                int(na)
            line.set_y1(weekH, _H)
            line.set_xy2(weekH, bar_index, _H)
            line.set_y1(weekL, _L)
            line.set_xy2(weekL, bar_index, _L)
            line.set_x2(weekO, bar_index)
            int(na)

// Weekly Range
if showHtf
    drawHTF(tfw, showHtfWeek, colorHtfWeek)

// Daily Range
if showHtf
    drawHTF(tfd, showHtfDay, colorHtfDay)

//––––––––––––––––––––TRUE DAILY OPEN––––––––––––––––––––
// Inputs
var grptdo = 'TDO Settings'
tdoShow = input.bool(true, title='', inline='1', group=grptdo)
tdoText = input.string("TDO", title='', inline='1', group=grptdo)
tdoColor = input.color(color.gray, title='', inline="1", group=grptdo)
MAX_LINES = input.int(300, title='Max Lines to show', minval=0, maxval=500, group=grptdo)
tdoOffset = input.int(0, "UTC Timezone offset (in hours)", minval = -12, maxval = 14, step = 1, tooltip = TOOLTIP01)

// Functions
markTimePrice(_hour,_minute,_second) =>
    inTDO = hour == _hour-hoursOffset-tdoOffset and minute == _minute-minutesOffset and second == _second

    var line[] tdoHline = array.new_line(0)
    var line[] tdoVline = array.new_line(0)
    var label[] tdoLabel = array.new_label(0)


    if inTDO and not inTDO[1] and tdoShow
        array.push(tdoHline, line.new(time, open, time + _24H, open, xloc=xloc.bar_time, color=tdoColor, style = line.style_dotted, width=linesWidth))
        array.push(tdoVline, line.new(time, open, time, close, xloc=xloc.bar_time, extend=extend.both,color=tdoColor, style = line.style_dotted, width=linesWidth))
        if showLable
            array.push(tdoLabel, label.new(time + _24H, open + open/LABEL_OFFSET_Y, tdoText, xloc=xloc.bar_time, style=label.style_none, size=labelSize, textcolor=tdoColor))
        
    // Delete lines if more than max
    if array.size(tdoHline) > MAX_LINES
        line.delete(array.shift(tdoHline))
        // label.delete(array.shift(tdoLabel))
    if array.size(tdoVline) > MAX_LINES
        line.delete(array.shift(tdoVline))


// Main
markTimePrice(5,0,0)


//––––––––––––––––––––INTRADAY SESSION––––––––––––––––––––
//Inputs
var grpss = 'Session Settings'
showLines = input(title='Show Lines ?', defval=true, group=grpss)
showVlines = input(title='Show VLines ?', defval=false, group=grpss)
extendVlines = input(title='Extend VLines ?', defval=false, group=grpss)
showOpenLine = input(title='Show Open Line ?', defval=true, group=grpss)
showMiddleLine = input(title='Show Middle Line ?', defval=true, group=grpss)
extendLines = input(title='Extend Lines ?', defval=false, group=grpss)
extendTime = input.session(title='Extended Lines Time', defval='0300-1659', group=grpss)
showBackground = input(title='Show Background ?', defval=false, group=grpss)


// Functions
fillSessBox (startTime, high_val, low_val, _color)=> 
    box.new(startTime, high_val, time, low_val, xloc=xloc.bar_time, bgcolor=_color, border_width=0)

drawSessHline (startTime, y_val, _color) =>
    line.new(startTime, y_val, time, y_val, xloc=xloc.bar_time, color=_color, style=line.style_solid, width=linesWidth)

drawSessVline (_x1, _y1, _x2, _y2) =>
    line.new(_x1, _y1, _x2, _y2, xloc=xloc.bar_time, extend = extendVlines ? extend.both : extend.none ,color=color.gray, style=line.style_dotted, width=linesWidth)

drawSessMline (startTime, high_val, low_val, _color) =>
    line.new(startTime, (high_val + low_val) / 2, time, (high_val + low_val) / 2, xloc=xloc.bar_time, color=_color, style=line.style_dotted, width=linesWidth)

drawSessLabel (startTime, high_val, sessLable ,_color) =>
    label.new(x = startTime, y = high_val + high_val/LABEL_OFFSET_Y, text = sessLable, xloc = xloc.bar_time, style=label.style_none, size=labelSize, textcolor = _color)
    
isTfBetweenMins(lowerMinute, upperMinute) =>
    timeframe.isintraday and timeframe.multiplier >= lowerMinute and timeframe.multiplier <= upperMinute


drawSessBox (showSess, rangeTime, sessLable, boxLineColor, middleLineColor, bgColor) =>
    inSession = not na(time(timeframe.period, rangeTime, utcOffset))
    inExtend = not na(time(timeframe.period, rangeTime, utcOffset))
    startTime = 0
    startTime := inSession and not inSession[1] ? time : startTime[1]

    //Box lines
    var line lowHline = na
    var line topHline = na
    var line leftVline = na
    var line rightVline = na
    var line middleHline = na
    var line openHline = na
    var box bgBox = na
    var label sLable = na

    var low_val = 0.0
    var high_val = 0.0
    var open_val = 0.0
    if inSession and not inSession[1]
        low_val := low
        high_val := high
        open_val := open
        high_val

    // Plot lines
    if showSession and inSession and isTfBetweenMins(1,59) and showSess
        if inSession[1]
            label.delete(sLable)
            line.delete(lowHline)
            line.delete(topHline)
            line.delete(leftVline)
            line.delete(rightVline)
            line.delete(middleHline)
            line.delete(openHline)
            box.delete(bgBox)
            int(na)

        if low < low_val
            low_val := low
            int(na)
        if high > high_val
            high_val := high
            int(na)

        //Create Box
        //x1, y1, x2, y2
        if showBackground
            bgBox := fillSessBox(startTime, high_val, low_val, bgColor)
            int(na)

        if showLines
            lowHline := drawSessHline(startTime, low_val, boxLineColor)
            topHline := drawSessHline(startTime, high_val, boxLineColor)
            if showVlines
                leftVline := drawSessVline(startTime, high_val, startTime, low_val)
                rightVline := drawSessVline(time, high_val, time, low_val)
                int(na)
            if showMiddleLine
                middleHline := drawSessMline(startTime, high_val, low_val, middleLineColor)
                int(na)
            if showOpenLine
                openHline := drawSessHline(startTime, open_val, boxLineColor)
                high_val
            int(na)
        if showLable
            sLable := drawSessLabel(startTime, high_val, sessLable, boxLineColor)
            int(na)

    else
        if inExtend and extendLines and not inSession and timeframe.isminutes
            time1 = line.get_x1(lowHline)
            time2 = line.get_x2(lowHline)
            price = line.get_y1(lowHline)
            line.delete(lowHline)
            lowHline := drawSessHline(time1, price, boxLineColor)
            
            time1 := line.get_x1(topHline)
            time2 := line.get_x2(topHline)
            price := line.get_y1(topHline)
            line.delete(topHline)
            topHline := drawSessHline(time1, price, boxLineColor)

            time1 := line.get_x1(middleHline)
            time2 := line.get_x2(middleHline)
            price := line.get_y1(middleHline)
            line.delete(middleHline)
            middleHline := drawSessMline(time1, price, price, middleLineColor)
            int(na)

//Main Session 1
var GRP1 = "Session 1"
showSess1 = input.bool(defval = true, title = "Show Session?", group = GRP1)
rangeTime1 = input.session(title='Session Time', defval='0000-0605', group=GRP1)
sessLable1 = input.string(defval = "ASIA", title = "Name", group = GRP1) 
boxLineColor1 = input(color.blue, 'Box and H/L Line Color', group=GRP1)
middleLineColor1 = input(color.blue, 'Middle Line Color', group=GRP1)
bgColor1 = input(color.new(color.aqua, 90), 'Box Background Color', group=GRP1)

drawSessBox(showSess1, rangeTime1, sessLable1, boxLineColor1, middleLineColor1, bgColor1)

//Main Session 2
var GRP2 = "Session 2"
showSess2 = input.bool(defval = true, title = "Show Session?", group = GRP2)
rangeTime2 = input.session(title='Session Time', defval='0700-1605', group=GRP2)
sessLable2 = input.string(defval = "LONDON", title = "Name", group = GRP2)
boxLineColor2 = input(color.green, 'Box and H/L Line Color', group=GRP2)
middleLineColor2 = input(color.green, 'Middle Line Color', group=GRP2)
bgColor2 = input(color.new(color.green, 90), 'Box Background Color', group=GRP2)

drawSessBox(showSess2, rangeTime2, sessLable2, boxLineColor2, middleLineColor2, bgColor2)

//Main Session 3
var GRP3 = "Session 3"
showSess3 = input.bool(defval = true, title = "Show Session?", group = GRP3)
rangeTime3 = input.session(title='Session Time', defval='1300-1705', group=GRP3)
sessLable3 = input.string(defval = "NEWYORK AM", title = "Name", group = GRP3)
boxLineColor3 = input(color.red, 'Box and H/L Line Color', group=GRP3)
middleLineColor3 = input(color.red, 'Middle Line Color', group=GRP3)
bgColor3 = input(color.new(color.red, 90), 'Box Background Color', group=GRP3)

drawSessBox(showSess3, rangeTime3, sessLable3, boxLineColor3, middleLineColor3, bgColor3)

//Main Session 4
var GRP4 = "Session 4"
showSess4 = input.bool(defval = true, title = "Show Session?", group = GRP4)
rangeTime4 = input.session(title='Session Time', defval='1800-2205', group=GRP4)
sessLable4 = input.string(defval = "NEWYORK PM", title = "Name", group = GRP4)
boxLineColor4 = input(color.red, 'Box and H/L Line Color', group=GRP4)
middleLineColor4 = input(color.red, 'Middle Line Color', group=GRP4)
bgColor4 = input(color.new(color.red, 90), 'Box Background Color', group=GRP4)

drawSessBox(showSess4, rangeTime4, sessLable4, boxLineColor4, middleLineColor4, bgColor4)

//Main Session 5
//var GRP5 = "Session 5"
//showSess5 = input.bool(defval = true, title = "Show Session?", group = GRP5)    
//rangeTime5 = input.session(title='Session Time', defval='0000-2345', group=GRP5)
//sessLable5 = input.string(defval = "DAILY RANGE", title = "Name", group = GRP5)
//boxLineColor5 = input(color.black, 'Box and H/L Line Color', group=GRP5)
//middleLineColor5 = input(color.black, 'Middle Line Color', group=GRP5)
//bgColor5 = input(color.new(color.black, 90), 'Box Background Color', group=GRP5)

//drawSessBox(showSess5, rangeTime5, sessLable5, boxLineColor5, middleLineColor5, bgColor5)

Overview

ICT Time Range draws session boxes with optional high, low, open, and middle lines, labels, and background shading, and it can extend those lines through a chosen time window. Separate weekly and daily range lines track each higher timeframe’s high, low, and open, with colors and visibility toggled independently. Timezone hour and minute offsets shift the session clocks. The visible code does not define trade entries, exits, or stop logic.

Details

Published by

vitahoang on GitHub

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

SMC / ICT / price action, Sessions & time, Support & resistance

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Show Session?booltrueshowSession
Show Lable?booltrueshowLable
Timezone offset (hrs)int0hoursOffset
Timezone offset (mins)int0minutesOffset
Lines Widthint1linesWidth
Label SizestringSmall_labelSize
Show HTF Range?booltrueshowHtf
Show Weekly Range?booltrueshowHtfWeek
colorHtfWeekcolorcolor.orangecolorHtfWeek
Show Daily Range?booltrueshowHtfDay
colorHtfDaycolorcolor.graycolorHtfDay
TimeframetimeframeWtfw
Show all 40 settings
SettingTypeDefaultVariable
TimeframetimeframeDtfd
tdoShowbooltruetdoShow
tdoTextstringTDOtdoText
tdoColorcolorcolor.graytdoColor
Max Lines to showint300MAX_LINES
UTC Timezone offset (in hours)int0tdoOffset
Show Lines ?booltrueshowLines
Show VLines ?boolfalseshowVlines
Extend VLines ?boolfalseextendVlines
Show Open Line ?booltrueshowOpenLine
Show Middle Line ?booltrueshowMiddleLine
Extend Lines ?boolfalseextendLines
Extended Lines Timesession0300-1659extendTime
Show Background ?boolfalseshowBackground
Show Session?booltrueshowSess1
Session Timesession0000-0605rangeTime1
NamestringASIAsessLable1
Box and H/L Line Colorcolorcolor.blueboxLineColor1
Middle Line Colorcolorcolor.bluemiddleLineColor1
Box Background Colorcolorcolor.new(color.aqua, 90)bgColor1
Show Session?booltrueshowSess2
Session Timesession0700-1605rangeTime2
NamestringLONDONsessLable2
Box and H/L Line Colorcolorcolor.greenboxLineColor2
Middle Line Colorcolorcolor.greenmiddleLineColor2
Box Background Colorcolorcolor.new(color.green, 90)bgColor2
Show Session?booltrueshowSess3
Session Timesession1300-1705rangeTime3
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

Golden Bullet Strategy

by TradersPost
218 stars

The Golden Bullet Strategy is an overlay signal indicator based on Smart Money Concepts and time-based liquidity models. It identifies liquidity sweeps of a designated reference session range during a specified hunt window. It then confirms Market Structure Sh

Indicator v6 SMC / ICT / price actionSessions & time
Updated 3 months ago · None stated GitHub repository of Golden Bullet Strategy

This indicator detects and draws the first Fair Value Gap (FVG) that forms in each hourly session based on a selected lower timeframe, with specialized handling for Regular Trading Hours (RTH) confluence windows. It draws FVG range boxes, midpoint lines, hourl

Indicator v5 SMC / ICT / price actionSupport & resistance Repaints

This indicator combines six trading tools into a single chart overlay to optimize indicator limits. It calculates Bollinger Bands, projects weekend price boundaries, plots market structure elements like order blocks, breaker blocks, and MSB lines, marks New Yo

Indicator v6 Support & resistanceSMC / ICT / price action Repaints
19 stars

This indicator highlights Inner Circle Trader (ICT) killzones and key session pivot points directly on the price chart. It projects shaded boxes for specific trading sessions, including Asia, London, NY AM, NY Lunch, and NY PM, to help traders identify high-li

Indicator v5 SMC / ICT / price actionSessions & time
Updated 3 years ago · MIT GitHub repository of ICT Killzones & Pivots

Bandz Session Ranges + ORG + Opening Prices plots trading session ranges, killzones, opening RTH gaps, standard deviation projections, and key opening prices directly on the price chart. It calculates gap ranges based on prior regular trading hours close sourc

Indicator v6 Sessions & timeSupport & resistance
Updated 2 weeks ago · MPL-2.0 GitHub repository of Bandz Session Ranges + ORG + Opening Prices

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers