Range Bound - Rev NR - 12-25-22
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © hockeydude84

//@version=5
indicator("Range Bound - Rev NR - 12-25-22", overlay=true, precision = 2) 

//Range Bound Code was created by @HockeyDude84
//Range Bound Rev NR - Released on 12-25-2022

//RangeBound - Code tracks price action within a user specified range (lookback), and tracks/charts overall high/lows, open high/lows, and close high/lows 
//Code resets certain parameters based on break of range to assist with determine price action - Can be useful to determine resistances to movement regardless of S&R levels
//Code also uses the previous 5X Close High/Lows ranges as will chart as support and resitance to assist with determine resistance to price action
//Note if using "redraw" shorter lookcback periods will take additional time to compile due to multiple "redraws/deletes of previous lines" Uncheck redraw to reduce compile time

//The first code I have decided to publish

////////////////////////////
//Range Bounding ///////////
////////////////////////////

//User inputs 
var RB = "Range Bound Inputs"
lookback = input.int(100, title='Lookback Length for Range (Default=100)', minval=1, group=RB)

//Variable Set Up
rangeHigh = ta.highest(high, lookback)
rangeLow = ta.lowest(low, lookback)
rangeOpenHigh = ta.highest(open, lookback)
rangeOpenLow = ta.lowest(open, lookback)
rangeCloseHigh = ta.highest(close, lookback)
rangeCloseLow = ta.lowest(close, lookback)

//Plot Highs and Lows - These are the outer brackets
plot(rangeHigh, color=color.aqua)
plot(rangeLow, color=color.aqua)

//Range Breaks - Look to determine when a range break occurs
rangeHighChange = rangeHigh <=rangeHigh[1] ? 1 : 0
rangeLowChange = rangeLow >=rangeLow[1] ? 1 : 0
rangeOpenHighChange = rangeOpenHigh <=rangeOpenHigh[1] ? 1 : 0
rangeOpenLowChange = rangeOpenLow >=rangeOpenLow[1] ? 1 : 0
rangeCloseHighChange = rangeCloseHigh <=rangeCloseHigh[1] ? 1 : 0
rangeCloseLowChange = rangeCloseLow >=rangeCloseLow[1] ? 1 : 0


//Determine and draw the ranges

//High
var rangeHighCounter = 1
rangeHighCounter := rangeLowChange ==0 ? 1: rangeHighCounter+1
rangeHighFinalLength = rangeHighCounter < lookback ? rangeHighCounter : lookback
rangeHighFinal = ta.highest(high, rangeHighFinalLength)
plot(rangeHighFinal, color=color.lime, linewidth=3) 

//Low
var rangeLowCounter = 1
rangeLowCounter := rangeHighChange ==0 ? 1: rangeLowCounter+1
rangeLowFinalLength = rangeLowCounter < lookback ? rangeLowCounter : lookback
rangeLowFinal = ta.lowest(low, rangeLowFinalLength)
plot(rangeLowFinal, color=color.red, linewidth=3)

//Open High 
var rangeOpenHighCounter = 1
rangeOpenHighCounter := rangeOpenHighChange ==0 ? 1: rangeOpenHighCounter+1
rangeOpenHighFinalLength = rangeOpenHighCounter < lookback ? rangeOpenHighCounter : lookback
rangeOpenHighFinal = ta.highest(open, rangeOpenHighFinalLength)
plot(rangeOpenHighFinal, color=color.green, linewidth=2)


//Open low
var rangeOpenLowCounter = 1
rangeOpenLowCounter := rangeOpenLowChange ==0 ? 1: rangeOpenLowCounter+1
rangeOpenLowFinalLength = rangeOpenLowCounter < lookback ? rangeOpenLowCounter : lookback
rangeOpenLowFinal = ta.lowest(open, rangeOpenLowFinalLength)
plot(rangeOpenLowFinal, color=color.fuchsia, linewidth=2)


//Close High
var rangeCloseHighCounter = 1
rangeCloseHighCounter := rangeCloseHighChange ==0 ? 1: rangeCloseHighCounter+1
rangeCloseHighFinalLength = rangeCloseHighCounter < lookback ? rangeCloseHighCounter : lookback
rangeCloseHighFinal = ta.highest(close, rangeCloseHighFinalLength)
plot(rangeCloseHighFinal, color=color.olive, linewidth=1)

//Close Low
var rangeCloseLowCounter = 1
rangeCloseLowCounter := rangeCloseLowChange ==0 ? 1: rangeCloseLowCounter+1
rangeCloseLowFinalLength = rangeCloseLowCounter < lookback ? rangeCloseLowCounter : lookback
rangeCloseLowFinal = ta.lowest(close, rangeCloseLowFinalLength) 
plot(rangeCloseLowFinal, color=color.orange, linewidth=1)

////////////////////////////
//Support and Resistances //
////////////////////////////

//Use the previously determine ranges for Close High/Low to chart support and resistances

//User Inputs
var S_and_R = "Support and Resistance"
UseChart = input(true, title='Chart Support and Resistance)', group=S_and_R)
UseChartRedraw = input(true, title='Redraw S&R at Each Rangebreak - Reduces Chart Clutter (Default = Yes)', group=S_and_R)
UseLines = (UseChart==true and UseChartRedraw==true) ? 1 : 0
UsePlots = (UseChart==true and UseChartRedraw==false) ? 1 : 0

float preCloseHigh1 = 0
float preCloseHigh2 = 0
float preCloseHigh3 = 0
float preCloseHigh4 = 0
float preCloseHigh5 = 0

HighTrigger = rangeCloseHighChange==0 and rangeCloseHighFinal[1]==rangeCloseHighFinal[14] ? 1 : 0

preCloseHigh1 := HighTrigger==1 ? rangeCloseHighFinal[1] :preCloseHigh1[1]
preCloseHigh2 := HighTrigger==1 ? preCloseHigh1[1] :preCloseHigh2[1]
preCloseHigh3 := HighTrigger==1 ? preCloseHigh2[1] :preCloseHigh3[1]
preCloseHigh4 := HighTrigger==1 ? preCloseHigh3[1] :preCloseHigh4[1]
preCloseHigh5 := HighTrigger==1 ? preCloseHigh4[1] :preCloseHigh5[1]

if(HighTrigger==1 and UseLines==1)
    var line h1 = na
    var line h2 = na
    var line h3 = na
    var line h4 = na
    var line h5 = na
    line.delete(h1)
    line.delete(h2)
    line.delete(h3)
    line.delete(h4)
    line.delete(h5)
    h1 := line.new(bar_index, preCloseHigh1, bar_index-14, preCloseHigh1, color=color.black, extend=extend.left, style=line.style_dashed)
    h2 := line.new(bar_index, preCloseHigh2, bar_index-14, preCloseHigh2, color=color.black, extend=extend.left, style=line.style_dashed)
    h3 := line.new(bar_index, preCloseHigh3, bar_index-14, preCloseHigh3, color=color.black, extend=extend.left, style=line.style_dashed)
    h4 := line.new(bar_index, preCloseHigh4, bar_index-14, preCloseHigh4, color=color.black, extend=extend.left, style=line.style_dashed)
    h5 := line.new(bar_index, preCloseHigh5, bar_index-14, preCloseHigh5, color=color.black, extend=extend.left, style=line.style_dashed)


plot(UsePlots==1 ? preCloseHigh1 : na, color=color.black)
plot(UsePlots==1 ? preCloseHigh2 : na, color=color.black)
plot(UsePlots==1 ? preCloseHigh3 : na, color=color.black)
plot(UsePlots==1 ? preCloseHigh4 : na, color=color.black)
plot(UsePlots==1 ? preCloseHigh5 : na, color=color.black)

////// 
//Lows

float preCloseLow1 = 0
float preCloseLow2 = 0
float preCloseLow3 = 0
float preCloseLow4 = 0
float preCloseLow5 = 0

LowTrigger =  rangeCloseLowChange==0 and rangeCloseLowFinal[1]==rangeCloseLowFinal[14] ? 1 : 0

preCloseLow1 := LowTrigger==1 ? rangeCloseLowFinal[1] :preCloseLow1[1]
preCloseLow2 := LowTrigger==1 ? preCloseLow1[1] :preCloseLow2[1]
preCloseLow3 := LowTrigger==1 ? preCloseLow2[1] :preCloseLow3[1]
preCloseLow4 := LowTrigger==1 ? preCloseLow3[1] :preCloseLow4[1]
preCloseLow5 := LowTrigger==1 ? preCloseLow4[1] :preCloseLow5[1]

if(LowTrigger==1 and UseLines==1)
    var line l1 = na
    var line l2 = na
    var line l3 = na
    var line l4 = na
    var line l5 = na
    line.delete(l1)
    line.delete(l2)
    line.delete(l3)
    line.delete(l4)
    line.delete(l5)
    l1 := line.new(bar_index, preCloseLow1, bar_index-14, preCloseLow1, color=color.gray, extend=extend.left, style=line.style_dashed)
    l2 := line.new(bar_index, preCloseLow2, bar_index-14, preCloseLow2, color=color.gray, extend=extend.left, style=line.style_dashed)
    l3 := line.new(bar_index, preCloseLow3, bar_index-14, preCloseLow3, color=color.gray, extend=extend.left, style=line.style_dashed)
    l4 := line.new(bar_index, preCloseLow4, bar_index-14, preCloseLow4, color=color.gray, extend=extend.left, style=line.style_dashed)
    l5 := line.new(bar_index, preCloseLow5, bar_index-14, preCloseLow5, color=color.gray, extend=extend.left, style=line.style_dashed)


plot(UsePlots==1 ? preCloseLow1 : na, color=color.gray)
plot(UsePlots==1 ? preCloseLow2 : na, color=color.gray)
plot(UsePlots==1 ? preCloseLow3 : na, color=color.gray)
plot(UsePlots==1 ? preCloseLow4 : na, color=color.gray)
plot(UsePlots==1 ? preCloseLow5 : na, color=color.gray)