Indicator · Pine Script v5 · On the chart

Session First Bar Range

by TamaraKGreen· code credited to notprofessorgreen

Session First Bar Range calculates and projects the high, low, and mid-level of the opening bar of a specified higher timeframe session.

View on GitHub

Repaints

GitHub stars46on the repository
Pine versionv5runs as is
Lines of code237
Settings34inputs
LicenceNone statedfile: MPL-2.0
Last update7 weeks ago4 Sep 2026

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

237 lines of Pine Script v5 from Session First Bar Range.txt, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

Session First Bar Range.txt
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © notprofessorgreen

//@version=5
indicator(title='Session First Bar Range', shorttitle='FBR', overlay=true, max_lines_count=500, max_labels_count=500, max_boxes_count = 500, max_bars_back = 5000)

//-------------------------------------------------------------------------------------------------
// Inputs
//-------------------------------------------------------------------------------------------------
resolution  = input.timeframe("240", "Resolution", tooltip="Select any timeframe for the range calculation")
timeframe   = input.timeframe("15", "Timeframe")
midLine     = input.bool(true, "Show Midline")
hist        = input.bool(true, "Show Historical Ranges")
showL       = input.bool(true, "Show High/Low/Mid Labels", inline="Labels", group="Opening bar format")
showP       = input.bool(false, "Show Prices", inline="Labels", group="Opening bar format")
pos         = input.string("Left", "Position", options=["Left", "Right"], group="Opening bar format")
boxStyle    = input.string("──────", "Range : ", options=["──────", "─ ─ ─ ─", "· · · · · ·"], inline="Box", group="Opening bar format")
lineStyle   = input.string("─ ─ ─ ─", "MidLine : ", options=["──────", "─ ─ ─ ─", "· · · · · ·"], inline="Line", group="Opening bar format")
borderWidth = input.int(1, ' / ', 1, 10, inline="Box", group="Opening bar format")
lineWidth   = input.int(1, ' / ', 1, 10, inline="Line", group="Opening bar format")
_color      = input.color(color.rgb(4, 54, 146), "Color : ", inline="Color", group="Opening bar format")
_fillcolor  = input.color(color.rgb(9, 136, 209, 85), " / ", inline="Color", group="Opening bar format")

// Inputs for statistical levels
lookback        = input.int(60, "Lookback Periods for Stats", minval=1, group="Statistical Levels")
show_stats      = input.bool(true, "Show Statistical Levels", group="Statistical Levels")
show_stats_labels = input.bool(true, "Show Statistical Labels", group="Statistical Levels")
std_mult1       = input.float(1.0, "Std Dev Multiplier 1", minval=0, step=0.5, group="Statistical Levels")
std_mult2       = input.float(2.0, "Std Dev Multiplier 2", minval=0, step=0.5, group="Statistical Levels")
stats_line_color = input.color(color.purple, "Stats Line Color", group="Statistical Levels")
stats_line_width = input.int(1, "Stats Line Width", minval=1, maxval=10, group="Statistical Levels")
stats_label_color = input.color(color.purple, "Stats Label Color", group="Statistical Levels")
stats_label_size = input.string("Normal", "Stats Label Size", options=["Tiny", "Small", "Normal", "Large", "Huge"], group="Statistical Levels")

// Inputs for Fibonacci Extensions
show_mm         = input.bool(false, title="Show Fib Extensions", group="Fibonacci Extensions")
show_mm_labels  = input.bool(false, title="Show Fib Labels", group="Fibonacci Extensions")
mm_line_color   = input.color(color.teal, "Fib Line Color", group="Fibonacci Extensions")
mm_line_width   = input.int(1, "Fib Line Width", minval=1, maxval=10, group="Fibonacci Extensions")
mm_label_color  = input.color(color.teal, "Fib Label Color", group="Fibonacci Extensions")
mm_label_size   = input.string("Normal", "Fib Label Size", options=["Tiny", "Small", "Normal", "Large", "Huge"], group="Fibonacci Extensions")

// Add input for maximum history to display
max_history = input.int(20, "Maximum Historical Ranges", minval=1, maxval=100, group="Performance")

//-------------------------------------------------------------------------------------------------
// Functions / Calculations
//-------------------------------------------------------------------------------------------------
get_style(style) =>
    switch style
        "──────"        => line.style_solid
        "─ ─ ─ ─"       => line.style_dashed
        "· · · · · ·"   => line.style_dotted

get_label_size(size) =>
    switch size
        "Tiny"   => size.tiny
        "Small"  => size.small
        "Normal" => size.normal
        "Large"  => size.large
        "Huge"   => size.huge

[newBar, end] = request.security(syminfo.tickerid, resolution, [time, time_close], lookahead=barmerge.lookahead_on)
[H, L, M]     = request.security(ticker.standard(syminfo.tickerid), timeframe, [high, low, hl2], lookahead=barmerge.lookahead_on)

start       = time(resolution)
isNewPeriod = ta.change(newBar) != 0

_style = pos == "Left" ? label.style_label_right : label.style_label_left
x      = pos == "Left" ? start : end

// Arrays to store drawing objects for better management
var line_array = array.new<line>()
var label_array = array.new<label>()
var linefill_array = array.new<linefill>()

// Calculate statistical levels based on past ranges
var float[] range_array = array.new_float(0)
if isNewPeriod
    array.push(range_array, H - L)
    if array.size(range_array) > lookback
        array.shift(range_array)

avg_range = array.avg(range_array)
std_dev = array.stdev(range_array)
stat_level1_up = H + avg_range + std_dev * std_mult1
stat_level1_dn = L - (avg_range + std_dev * std_mult1)
stat_level2_up = H + avg_range + std_dev * std_mult2
stat_level2_dn = L - (avg_range + std_dev * std_mult2)

// Range and Percentage Calculations
mm_1 = input.float(1.618, 'Measured move extension 1', group='Fibonacci Extensions')
mm_2 = input.float(2.618, 'Measured move extension 2', group='Fibonacci Extensions')
mm_3 = input.float(3.618, 'Measured move extension 3', group='Fibonacci Extensions')
mm_4 = input.float(4.618, 'Measured move extension 4', group='Fibonacci Extensions')
mm_5 = input.float(5.618, 'Measured move extension 5', group='Fibonacci Extensions')

_range = H - L
range_50 = L + _range * 0.50
range_100 = H 
range_200 = H + _range 
range_300 = H + _range * mm_1
range_400 = H + _range * mm_2
range_500 = H + _range * mm_3
range_600 = H + _range * mm_4
range_700 = H + _range * mm_5
neg_range_200 = L - _range
neg_range_300 = L - _range * mm_1
neg_range_400 = L - _range * mm_2
neg_range_500 = L - _range * mm_3
neg_range_600 = L - _range * mm_4
neg_range_700 = L - _range * mm_5

// Function to manage array size
manage_array_size(arr, max_size) =>
    while array.size(arr) > max_size
        old_element = array.shift(arr)
        line.delete(old_element)

manage_label_array_size(arr, max_size) =>
    while array.size(arr) > max_size
        old_element = array.shift(arr)
        label.delete(old_element)

manage_linefill_array_size(arr, max_size) =>
    while array.size(arr) > max_size
        old_element = array.shift(arr)
        linefill.delete(old_element)

//-------------------------------------------------------------------------------------------------
// Outputs
//-------------------------------------------------------------------------------------------------
// Draw elements
if isNewPeriod
    // Calculate how many objects we'll create per session
    objects_per_session = 2 + (midLine ? 1 : 0) + (show_stats ? 4 : 0) + (show_mm ? 8 : 0)
    labels_per_session = (showL ? (2 + (midLine ? 1 : 0)) : 0) + (show_stats_labels ? 4 : 0) + (show_mm_labels ? 8 : 0)
    
    // Adjust max_history based on object count to stay within limits
    adjusted_max_history = math.min(max_history, math.floor(450 / objects_per_session))
    adjusted_max_labels = math.min(max_history, math.floor(450 / math.max(labels_per_session, 1)))
    
    // Draw high, low, and midline
    _top = line.new(start, H, end, H, color=_color, style=get_style(boxStyle), width=lineWidth, xloc=xloc.bar_time)
    _bot = line.new(start, L, end, L, color=_color, style=get_style(boxStyle), width=lineWidth, xloc=xloc.bar_time)
    _fill = linefill.new(_top, _bot, _fillcolor)
    
    array.push(line_array, _top)
    array.push(line_array, _bot)
    array.push(linefill_array, _fill)
    
    if midLine
        _mid = line.new(start, M, end, M, color=_color, style=get_style(lineStyle), width=lineWidth, xloc=xloc.bar_time)
        array.push(line_array, _mid)
    
    if showL
        _label_high = label.new(x, H, "High" + (showP ? " (" + str.tostring(H, format.mintick) + ")" : ""), style=label.style_none, color=#000000cb, textcolor=_color, xloc=xloc.bar_time, size=get_label_size("Normal"))
        _label_low = label.new(x, L, "Low" + (showP ? " (" + str.tostring(L, format.mintick) + ")" : ""), style=label.style_none, color=#000000cb, textcolor=_color, xloc=xloc.bar_time, size=get_label_size("Normal"))
        array.push(label_array, _label_high)
        array.push(label_array, _label_low)
        if midLine
            _label_mid = label.new(x, M, "Mid" + (showP ? " (" + str.tostring(M, format.mintick) + ")" : ""), style=label.style_none, color=#000000cb, textcolor=_color, xloc=xloc.bar_time, size=get_label_size("Normal"))
            array.push(label_array, _label_mid)
    
    // Draw Fibonacci extensions
    if show_mm
        mm_line_200 = line.new(start, range_200, end, range_200, color=mm_line_color, width=mm_line_width, xloc=xloc.bar_time)
        mm_line_300 = line.new(start, range_300, end, range_300, color=mm_line_color, width=mm_line_width, xloc=xloc.bar_time)
        mm_line_400 = line.new(start, range_400, end, range_400, color=mm_line_color, width=mm_line_width, xloc=xloc.bar_time)
        mm_line_500 = line.new(start, range_500, end, range_500, color=mm_line_color, width=mm_line_width, xloc=xloc.bar_time)
        mm_line_neg_200 = line.new(start, neg_range_200, end, neg_range_200, color=mm_line_color, width=mm_line_width, xloc=xloc.bar_time)
        mm_line_neg_300 = line.new(start, neg_range_300, end, neg_range_300, color=mm_line_color, width=mm_line_width, xloc=xloc.bar_time)
        mm_line_neg_400 = line.new(start, neg_range_400, end, neg_range_400, color=mm_line_color, width=mm_line_width, xloc=xloc.bar_time)
        mm_line_neg_500 = line.new(start, neg_range_500, end, neg_range_500, color=mm_line_color, width=mm_line_width, xloc=xloc.bar_time)
        
        array.push(line_array, mm_line_200)
        array.push(line_array, mm_line_300)
        array.push(line_array, mm_line_400)
        array.push(line_array, mm_line_500)
        array.push(line_array, mm_line_neg_200)
        array.push(line_array, mm_line_neg_300)
        array.push(line_array, mm_line_neg_400)
        array.push(line_array, mm_line_neg_500)
        
        if show_mm_labels
            mm_label_200 = label.new(x, range_200, "100%", style=label.style_none, color=#000000cb, textcolor=mm_label_color, xloc=xloc.bar_time, size=get_label_size(mm_label_size))
            mm_label_300 = label.new(x, range_300, str.tostring(mm_1, "#.###") + "x", style=label.style_none, color=#000000cb, textcolor=mm_label_color, xloc=xloc.bar_time, size=get_label_size(mm_label_size))
            mm_label_400 = label.new(x, range_400, str.tostring(mm_2, "#.###") + "x", style=label.style_none, color=#000000cb, textcolor=mm_label_color, xloc=xloc.bar_time, size=get_label_size(mm_label_size))
            mm_label_500 = label.new(x, range_500, str.tostring(mm_3, "#.###") + "x", style=label.style_none, color=#000000cb, textcolor=mm_label_color, xloc=xloc.bar_time, size=get_label_size(mm_label_size))
            mm_label_neg_200 = label.new(x, neg_range_200, "-100%", style=label.style_none, color=#000000cb, textcolor=mm_label_color, xloc=xloc.bar_time, size=get_label_size(mm_label_size))
            mm_label_neg_300 = label.new(x, neg_range_300, "-" + str.tostring(mm_1, "#.###") + "x", style=label.style_none, color=#000000cb, textcolor=mm_label_color, xloc=xloc.bar_time, size=get_label_size(mm_label_size))
            mm_label_neg_400 = label.new(x, neg_range_400, "-" + str.tostring(mm_2, "#.###") + "x", style=label.style_none, color=#000000cb, textcolor=mm_label_color, xloc=xloc.bar_time, size=get_label_size(mm_label_size))
            mm_label_neg_500 = label.new(x, neg_range_500, "-" + str.tostring(mm_3, "#.###") + "x", style=label.style_none, color=#000000cb, textcolor=mm_label_color, xloc=xloc.bar_time, size=get_label_size(mm_label_size))
            
            array.push(label_array, mm_label_200)
            array.push(label_array, mm_label_300)
            array.push(label_array, mm_label_400)
            array.push(label_array, mm_label_500)
            array.push(label_array, mm_label_neg_200)
            array.push(label_array, mm_label_neg_300)
            array.push(label_array, mm_label_neg_400)
            array.push(label_array, mm_label_neg_500)
    
    // Draw statistical levels
    if show_stats
        stat_line1_up = line.new(start, stat_level1_up, end, stat_level1_up, color=stats_line_color, style=line.style_dashed, width=stats_line_width, xloc=xloc.bar_time)
        stat_line1_dn = line.new(start, stat_level1_dn, end, stat_level1_dn, color=stats_line_color, style=line.style_dashed, width=stats_line_width, xloc=xloc.bar_time)
        stat_line2_up = line.new(start, stat_level2_up, end, stat_level2_up, color=stats_line_color, style=line.style_dotted, width=stats_line_width, xloc=xloc.bar_time)
        stat_line2_dn = line.new(start, stat_level2_dn, end, stat_level2_dn, color=stats_line_color, style=line.style_dotted, width=stats_line_width, xloc=xloc.bar_time)
        
        array.push(line_array, stat_line1_up)
        array.push(line_array, stat_line1_dn)
        array.push(line_array, stat_line2_up)
        array.push(line_array, stat_line2_dn)
        
        if show_stats_labels
            stat_label1_up = label.new(x, stat_level1_up, "+" + str.tostring(std_mult1) + "σ", style=label.style_none, color=#000000cb, textcolor=stats_label_color, xloc=xloc.bar_time, size=get_label_size(stats_label_size))
            stat_label1_dn = label.new(x, stat_level1_dn, "-" + str.tostring(std_mult1) + "σ", style=label.style_none, color=#000000cb, textcolor=stats_label_color, xloc=xloc.bar_time, size=get_label_size(stats_label_size))
            stat_label2_up = label.new(x, stat_level2_up, "+" + str.tostring(std_mult2) + "σ", style=label.style_none, color=#000000cb, textcolor=stats_label_color, xloc=xloc.bar_time, size=get_label_size(stats_label_size))
            stat_label2_dn = label.new(x, stat_level2_dn, "-" + str.tostring(std_mult2) + "σ", style=label.style_none, color=#000000cb, textcolor=stats_label_color, xloc=xloc.bar_time, size=get_label_size(stats_label_size))
            
            array.push(label_array, stat_label1_up)
            array.push(label_array, stat_label1_dn)
            array.push(label_array, stat_label2_up)
            array.push(label_array, stat_label2_dn)
    
    // Manage array sizes to prevent hitting limits
    if not hist
        // If not showing history, keep only current period's objects
        manage_array_size(line_array, objects_per_session)
        manage_label_array_size(label_array, labels_per_session)
        manage_linefill_array_size(linefill_array, 1)
    else if array.size(line_array) > adjusted_max_history * objects_per_session
        // If showing history, manage when exceeding limits
        manage_array_size(line_array, adjusted_max_history * objects_per_session)
        manage_label_array_size(label_array, adjusted_max_labels * labels_per_session)
        manage_linefill_array_size(linefill_array, adjusted_max_history)

Overview

Session First Bar Range draws range boxes directly on the price chart, along with historical ranges, statistical standard deviation levels, and optional Fibonacci extensions. Users can customize resolution timeframes, lookback periods for statistical calculations, line styles, and label formats. Because it references higher-timeframe data, it includes lookahead risk.

Details

Published by

TamaraKGreen on GitHub

Code credit

notprofessorgreen, as written in the script's header

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Sessions & time, Support & resistance

Markets

Any symbol

Timeframes

M15-H1, H4 and above

Risk Notes

  • Reads higher-timeframe data with lookahead on, so the history can show signals that were not there in real time

Settings

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

SettingTypeDefaultVariable
Resolutiontimeframe240resolution
Timeframetimeframe15timeframe
Show MidlinebooltruemidLine
Show Historical Rangesbooltruehist
Show High/Low/Mid LabelsbooltrueshowL
Show PricesboolfalseshowP
PositionstringLeftpos
Range : string──────boxStyle
MidLine : string─ ─ ─ ─lineStyle
/ int1borderWidth
/ int1lineWidth
Color : colorcolor.rgb(4, 54, 146)_color
Show all 34 settings
SettingTypeDefaultVariable
/ colorcolor.rgb(9, 136, 209, 85)_fillcolor
Lookback Periods for Statsint60lookback
Show Statistical Levelsbooltrueshow_stats
Show Statistical Labelsbooltrueshow_stats_labels
Std Dev Multiplier 1float1.0std_mult1
Std Dev Multiplier 2float2.0std_mult2
Stats Line Colorcolorcolor.purplestats_line_color
Stats Line Widthint1stats_line_width
Stats Label Colorcolorcolor.purplestats_label_color
Stats Label SizestringNormalstats_label_size
Show Fib Extensionsboolfalseshow_mm
Show Fib Labelsboolfalseshow_mm_labels
Fib Line Colorcolorcolor.tealmm_line_color
Fib Line Widthint1mm_line_width
Fib Label Colorcolorcolor.tealmm_label_color
Fib Label SizestringNormalmm_label_size
Maximum Historical Rangesint20max_history
Measured move extension 1float1.618mm_1
Measured move extension 2float2.618mm_2
Measured move extension 3float3.618mm_3
Measured move extension 4float4.618mm_4
Measured move extension 5float5.618mm_5
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

575 stars

This indicator builds Market Profile Time Price Opportunity (TPO) structures across defined session timeframes directly on the main price chart. It visualizes the Point of Control (POC) and Value Area boundaries using dynamic box drawings. An integrated multi-

Indicator v5 Support & resistanceScreeners & dashboards
Updated 1 year ago · MPL-2.0 GitHub repository of Market Profile with Screener
257 stars

This indicator plots auto trade signals for E-mini S&P 500 futures on the price chart. It computes an EMA200 filter along with day ETH RTH session levels and percentage-based entry zones. Signals trigger CALL or PUT cases when price crosses defined thresholds

Indicator v6 TrendSupport & resistance
Updated 6 weeks ago · None stated GitHub repository of Auto Trade Futures ES
219 stars

This indicator plots reference levels for previous daily high and low prices directly on the price chart. It requests daily timeframe data using the security function and plots the offset values as continuous lines, displaying resistance in red and support in

Indicator v4 Support & resistanceSessions & time
Updated 5 years ago · None stated GitHub repository of 昨日高低點標示

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

Moon Dev GEX Arrows

by moondevonyt
92 stars

This overlay indicator plots option strike walls and an optional session VWAP on the price chart for SPY or ES. It spaces major strikes by the selected instrument, draws a set number of strikes on each side, and marks wall-trap and sweep events after a cooldow

Indicator v5 Support & resistanceSessions & time
Updated 8 weeks ago · Custom licence GitHub repository of Moon Dev GEX Arrows

Key Levels

by cryptorife
75 stars

This indicator plots reference levels and session markers directly on the price chart. It calculates and draws lines for the daily open, weekly open, monthly open, previous day OHLC, and previous week extremes, along with a selectable day-of-week range and ini

Indicator v4 Support & resistanceSessions & time Repaints
Updated 3 years ago · GPL-3.0 GitHub repository of Key Levels

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