Indicator · Pine Script v5 · On the chart

Opening Range

by g-moe· code credited to goodgains

This indicator overlays a Directional Sentiment Line ribbon on the price chart using moving averages of high, low, open, and close prices.

View on GitHub

Repaints

GitHub stars3on the repository
Pine versionv5runs as is
Lines of code193
Settings32inputs
LicenceNone statedfile: MPL-2.0
Last update5 months ago27 May 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

193 lines of Pine Script v5 from Tradingview/opening-range-v2.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

opening-range-v2.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © goodgains


//@version=5
indicator("Opening Range", overlay = true)

// @keywords: opening-range, directional-sentiment-line, sma-high-low-close, ribbon-fill, mtf-macd-filter, mtf-rsi-filter, volume-heatmap, stddev-volume-bars, buy-sell-barcolor, highest-lowest-targets, dsl-trend-side, volume-thresholds, heatmap-zscore, combined-buy-sell, alert-on-flip, sentiment-ribbon, macd-histogram-side, rsi-trigger-levels, volume-cluster, multi-confirm-entry


// diretional sentiment line
dsl_length = input.int(150, title = 'Length', minval = 2, group = 'Directional Sentiment Line', inline = '1')

hi = ta.sma(high, dsl_length)
lo = ta.sma(low, dsl_length)
cl = ta.sma(close, dsl_length) 
op = ta.sma(open, dsl_length) 

lowest = ta.lowest(lo, dsl_length)
highest = ta.highest(hi, dsl_length)

// bools for ribbon 
bool closeabove = close >= cl 
bool closebelow = close <= cl 
bool highabove = high >= hi 
bool lowabove = low >= lo 
bool openabove = open >= op 

// bools for highest/lowest 
bool paabovehigh = close > highest 
bool pabelowlow = close < lowest 
bool middle = close >= lo and close <= hi


// colors
color bull = color.green 
color bear = color.red 
color neutral = color.orange
color standard = color.blue
color fillcolorbull = color.new(color.green, 50)
color fillcolorbear = color.new(color.red, 50)
color fillcolorneutral = color.new(color.gray, 50)
color hicolor = highabove ? bull : bear 
color locolor = lowabove ? bull : bear 
color opcolor = openabove ? bull : bear 
color clcolor = closeabove ? bull : bear 
color lowestcolor = pabelowlow ? neutral : standard
color highestcolor = paabovehigh ? neutral : standard 
color fillfinal = closeabove ? fillcolorbull : closebelow ? fillcolorbear : middle ? fillcolorneutral : na 

// plots
hir = plot(hi, color = hicolor)
lor = plot(lo, color = locolor)
plot(cl, color = clcolor)
plot(op, color = opcolor)

fill(hir, lor, color = fillfinal, editable=false)

plot(lowest, "Lowest Target", color = lowestcolor, linewidth=3, display = display.none)
plot(highest, "Highest Target", color = highestcolor, linewidth=3, display = display.none)

dsl_side = closeabove ? 1 : closebelow ? -1 : middle ? 0 : na 



// macd 
macd_source = input.source(close, title = 'MACD Source', group = 'MACD', inline = '1')
macd_fast = input.int(12, title = 'MACD Fast', group = 'MACD', inline = '2')
macd_slow = input.int(26, title = 'MACD Slow', group = 'MACD', inline = '3')
macd_length = input.int(9, title = 'MACD Length', group = 'MACD', inline = '4')
macd_tf = input.timeframe('15', title = 'MACD Timeframe', group = 'MACD', inline = '5')
if timeframe.in_seconds(timeframe.period) > timeframe.in_seconds(macd_tf)
    runtime.error("Your MACD timeframe is lower than the main chart timeframe.")

macd_source_lookback = timeframe.in_seconds(timeframe.period) == timeframe.in_seconds(macd_tf) ? 0 : 1
[macdLine, signalLine, histLine] = request.security(syminfo.tickerid, macd_tf, ta.macd(macd_source[macd_source_lookback], macd_fast, macd_slow, macd_length), lookahead = barmerge.lookahead_on)
macd_side = histLine >= 0 ? 1 : -1


// rsi
rsi_source = input.source(close, title = 'RSI Source', group = 'RSI', inline = '1')
rsi_length = input.int(14, title = 'RSI Length', group = 'RSI', inline = '2')
rsi_above_trigger = input.int(50, title = 'Above Trigger', group = 'RSI', inline = '3')
rsi_below_trigger = input.int(50, title = 'Below Trigger', group = 'RSI', inline = '4')
rsi_tf = input.timeframe('15', title = 'RSI Timeframe', group = 'RSI', inline = '5')
if timeframe.in_seconds(timeframe.period) > timeframe.in_seconds(rsi_tf)
    runtime.error("Your RSI timeframe is lower than the main chart timeframe.")

rsi_source_lookback = timeframe.in_seconds(timeframe.period) == timeframe.in_seconds(rsi_tf) ? 0 : 1
rsi_value = request.security(syminfo.tickerid, rsi_tf, ta.rsi(rsi_source, rsi_length)[rsi_source_lookback], lookahead = barmerge.lookahead_on)
rsi_side = rsi_value > rsi_above_trigger ? 1 : rsi_value < rsi_below_trigger ? -1 : 0


// heatmap volume
hm_length = input.int(610, title="MA Length", minval=2, group = 'Heatmap', inline = '1')
hm_slength = input.int(610, title='Std Length', minval=2, group = 'Heatmap', inline = '2')

thresholdExtraHigh  = input.float(4, title="Extra High Volume Threshold", group = 'Heatmap', inline = '3')
thresholdHigh       = input.float(2.5, title="High Volume Threshold", group = 'Heatmap', inline = '4')
thresholdMedium     = input.float(1, title="Medium Volume Threshold", group = 'Heatmap', inline = '5')
thresholdNormal     = input.float(-0.5, title="Normal Volume Threshold", group = 'Heatmap', inline = '6')


// color
// up colors
cupthresholdExtraHigh = input(#00FF00, 'Up Extra High')
cupthresholdHigh      = input(#30FF30, 'Up High')
cupthresholdMedium    = input(#60FF60, 'Up Medium')
cupthresholdNormal    = input(#8FFF8F, 'Up Normal')
cupthresholdLow       = input(#BFFFBF, 'Up Low')


// down colors
cdnthresholdExtraHigh = input(#FF0000, 'Down Extra High')
cdnthresholdHigh      = input(#FF3030, 'Down High')
cdnthresholdMedium    = input(#FF6060, 'Down Medium')
cdnthresholdNormal    = input(#FF8F8F, 'Down Normal')
cdnthresholdLow       = input(#FFBFBF, 'Down Low')


// threshold colors
chm1 = #ff0000 // extra high red
chm2 = #ff7800 // high orange
chm3 = #ffcf03 // medium yellow
chm4 = #a0d6dc // normal
chm5 = #1f9cac // low

chmthresholdExtraHigh = input.color(chm1, 'Heatmap Extra High')
chmthresholdHigh      = input.color(chm2, 'Heatmap High')
chmthresholdMedium    = input.color(chm3, 'Heatmap Medium')
chmthresholdNormal    = input.color(chm4, 'Heatmap Normal')
chmthresholdLow       = input.color(chm5, 'Heatmap Low')

cthresholdExtraHighUp = chmthresholdExtraHigh 
cthresholdHighUp      = chmthresholdHigh 
cthresholdMediumUp    = chmthresholdMedium 
cthresholdNormalUp    = chmthresholdNormal
cthresholdLowUp       = chmthresholdLow

cthresholdExtraHighDn = chmthresholdExtraHigh
cthresholdHighDn      = chmthresholdHigh
cthresholdMediumDn    = chmthresholdMedium
cthresholdNormalDn    = chmthresholdNormal
cthresholdLowDn       = chmthresholdLow


hm_length := hm_length > bar_index + 1 ? bar_index + 1 : hm_length
hm_slength := hm_slength > bar_index + 1 ? bar_index + 1 : hm_slength


pstdev(Series, Period) =>
    mean = math.sum(Series, Period) / Period
    summation = 0.0
    for i=0 to Period-1
        sampleMinusMean = nz(Series[i]) - mean
        summation := summation + sampleMinusMean * sampleMinusMean
    math.sqrt(summation / Period)


mean    = ta.sma(volume, hm_length)
std     = pstdev(volume, hm_slength)
stdbar  = (volume - mean) / std
dir     = close > open
v       = volume
mosc    = mean

bcolor = stdbar > thresholdExtraHigh ? dir ? cthresholdExtraHighUp : cthresholdExtraHighDn :
  stdbar > thresholdHigh  ? dir ? cthresholdHighUp : cthresholdHighDn :
  stdbar > thresholdMedium ? dir ? cthresholdMediumUp : cthresholdMediumDn :
  stdbar > thresholdNormal ? dir ? cthresholdNormalUp : cthresholdNormalDn :
  dir ? cthresholdLowUp : cthresholdLowDn

hm_volume_cond = stdbar >= thresholdMedium

// conditions
buy_cond = dsl_side == 1 and macd_side == 1 and rsi_side == 1 and hm_volume_cond
sell_cond =  dsl_side == -1 and macd_side == -1 and rsi_side == -1 and hm_volume_cond

barcolor(buy_cond ? color.green : sell_cond ? color.red : color.gray)


// alerts
alertcondition(buy_cond and not buy_cond[1], title = 'Buy Alert', message = 'Buy Alert')
alertcondition(sell_cond and not sell_cond[1], title = 'Sell Alert', message = 'Sell Alert')







// if timeframe.in_seconds(timeframe.period) >= timeframe.in_seconds(rsi_tf)
//   runtime.error('RSI Timeframe cannot be less than the main chart')

Overview

Opening Range combines higher-timeframe MACD and RSI filters with standard deviation volume heatmap thresholds to assess directional bias and volume intensity. Main settings allow customization of the DSL length, MACD and RSI timeframes and parameters, standard deviation periods, and volume thresholds. Because it retrieves higher-timeframe data using lookahead, historical bars exhibit lookahead bias.

Details

Published by

g-moe on GitHub

Code credit

goodgains, as written in the script's header

Draws

On the price chart

Markets

Any symbol

Timeframes

Any timeframe

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
Lengthint150dsl_length
MACD Sourcesourceclosemacd_source
MACD Fastint12macd_fast
MACD Slowint26macd_slow
MACD Lengthint9macd_length
MACD Timeframetimeframe15macd_tf
RSI Sourcesourceclosersi_source
RSI Lengthint14rsi_length
Above Triggerint50rsi_above_trigger
Below Triggerint50rsi_below_trigger
RSI Timeframetimeframe15rsi_tf
MA Lengthint610hm_length
Show all 32 settings
SettingTypeDefaultVariable
Std Lengthint610hm_slength
Extra High Volume Thresholdfloat4thresholdExtraHigh
High Volume Thresholdfloat2.5thresholdHigh
Medium Volume Thresholdfloat1thresholdMedium
Normal Volume Thresholdfloat-0.5thresholdNormal
Up Extra Highcolor#00FF00cupthresholdExtraHigh
Up Highcolor#30FF30cupthresholdHigh
Up Mediumcolor#60FF60cupthresholdMedium
Up Normalcolor#8FFF8FcupthresholdNormal
Up Lowcolor#BFFFBFcupthresholdLow
Down Extra Highcolor#FF0000cdnthresholdExtraHigh
Down Highcolor#FF3030cdnthresholdHigh
Down Mediumcolor#FF6060cdnthresholdMedium
Down Normalcolor#FF8F8FcdnthresholdNormal
Down Lowcolor#FFBFBFcdnthresholdLow
Heatmap Extra Highcolorchm1chmthresholdExtraHigh
Heatmap Highcolorchm2chmthresholdHigh
Heatmap Mediumcolorchm3chmthresholdMedium
Heatmap Normalcolorchm4chmthresholdNormal
Heatmap Lowcolorchm5chmthresholdLow
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

Signal Strategy 15m

by tripolskypetr
72 stars

This indicator generates trend-following trade signals on the price chart by combining moving average crossovers with multi-factor filters. It triggers entry alerts when fast and slow EMAs cross in the direction of a baseline trend EMA, confirmed by non-extrem

Indicator v5 TrendMoving averages
Updated 5 days ago · MIT GitHub repository of Signal Strategy 15m
46 stars

This overlay indicator plots a SuperTrend using a 10-period ATR with a multiplier of 3, drawing up and down stop lines and a faint trend fill on the price chart. It compares a 9-period EMA with an 18-period EMA and a 12/26/9 MACD against its signal, and it req

Indicator v5 TrendOscillators & momentum
Updated 3 years ago · None stated GitHub repository of SuperTrend + MACD + EMA

Bte Acc

by f-cksociety
11 stars

Bte Acc is a chart indicator form of the PineCoders Backtesting and Trading Engine. It seeks an entry trigger from a main or alternate entry method, then checks trade direction, filters, date range, ATR readiness, and remaining capital before filling on the ne

Indicator v5 TrendOscillators & momentum Repaints
Updated 4 years ago · MPL-2.0 GitHub repository of Bte Acc
2 stars

MasterTrader V1 is an indicator that plots two exponential moving averages (fast length 9, slow length 21) and RSI (length 14) on the close price chart. It generates long entry signals when the fast EMA crosses above the slow EMA, RSI stays between 30 and 70,

Indicator v6 TrendOscillators & momentum
Updated 2 days ago · None stated GitHub repository of MasterTrader V1 Master Trader
1 stars

This indicator calculates dual Exponential Moving Averages alongside their slopes, normalized distance, and momentum to detect trend shifts on the price chart. It plots standard EMA crossovers while also assessing early warning conditions when EMAs approach ea

Indicator v6 TrendMoving averages
Updated 7 days ago · None stated GitHub repository of Gelişmiş EMA Trend Analizi
1 stars

This Pine Script indicator plots fast and slow EMA lines on the price chart to identify trend direction. It applies RSI and MACD filters to confirm momentum strength and checks volume against its average for confirmation. Buy signals trigger on fast EMA crossi

Indicator v6 TrendOscillators & momentum
Updated 2 months ago · Custom licence GitHub repository of Lesson 5 Buy Sell Logic Demo

More Trend scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

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

Compare brokers