Monthly Range Support & Resistance [QuantVue]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © QuantVue

//@version=5
indicator("Monthly Range Support & Resistance [QuantVue]", overlay = true, max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500)

//-----------------------------------------------//
//runtime errors
//-----------------------------------------------//
if (timeframe.in_seconds() / 60 < timeframe.in_seconds('60') / 60)
    runtime.error('Please switch to 60 minute chart or higher')

//-----------------------------------------------//
//inputs
//-----------------------------------------------//
showTable = input.bool(true, 'Show Stats on Monthly Chart', inline = '1')
yPos = input.string("Top", " ", options = ["Top", "Middle", "Bottom"], inline = '1')
xPos = input.string("Right", " ", options = ["Right","Center", "Left"], inline = '1')
statsBG = input.color(color.gray, 'Stats Table BG Color', inline = '2')
statsText = input.color(color.white, 'Stats Table Text Color', inline = '2')

averagingPerdiod = input.int(7, 'Averaging Period', minval = 3, step = 1)
multiplier = input.float(1.0, 'StDev Multiplier', minval = .25, maxval = 4, step = .25)

sLineColor = input.color(color.blue, 'Support Color', inline = '3')
rLineColor = input.color(color.rgb(255, 17, 0), 'Resistance Color', inline = '3')
showFill = input.bool(true, 'Fill', inline = '3')
showPrice = input.bool(true, 'Show Support / Resistance Prices', inline = '4')
labelTextColor = input.color(color.white, ' ', inline = '4')

showWO = input.bool(true, 'Show Monthly Open Line', inline = '5')
wOColor = input.color(color.fuchsia, ' ', inline = '5')
r1Style = input.string('Solid', 'R1 Line Style', ['Solid', 'Dashed', 'Dotted'], inline = '6')
r2Style = input.string('Solid', 'R2 Line Style', ['Solid', 'Dashed', 'Dotted'], inline = '6')
s1Style = input.string('Solid', 'S1 Line Style', ['Solid', 'Dashed', 'Dotted'], inline = '7')
s2Style = input.string('Solid', 'S2 Line Style', ['Solid', 'Dashed', 'Dotted'], inline = '7')
showPrevious = input.bool(false, 'Show Previous Levls')

//-----------------------------------------------//
//methods
//-----------------------------------------------//
method switcher(string this) =>
    switch this
        'Solid' => line.style_solid
        'Dashed' => line.style_dashed
        'Dotted' => line.style_dotted

//-----------------------------------------------//
//variables
//-----------------------------------------------//
var table stats = table.new(str.lower(yPos) + '_' + str.lower(xPos), 5, 4, border_color = color.new(color.white,100), border_width = 2,
     frame_color = color.new(color.white,100), frame_width = 2)

var float[] upAvgArray = array.new<float>()
var float[] downAvgArray = array.new<float>()

var line r1Line = na, var line r2Line = na, var line s1Line = na, var line s2Line = na, var line WO = na 
var label r1Label = na, var label r2Label = na, var label s1Label = na, var label s2Label = na, var label WOLabel = na
var box rFill = na, var box sFill = na
var monthCount = 0, var closeAboveR1 = 0, var closeAboveR2 = 0, var closeBelowS1 = 0, var closeBelowS2 = 0
var touchR1 = 0, var touchR2 = 0, var touchS1 = 0, var touchS2 = 0
var R1 = 0.0, var R2 = 0.0, var S1 = 0.0, var S2 = 0.0
var monthIndex = 0

[monthOpen, monthHigh, monthLow, monthClose] = request.security(syminfo.tickerid, 'M',[open,high,low,close], lookahead = barmerge.lookahead_on)
newmonth = ta.change(time('M'))
idxCount = ta.barssince(newmonth)

//-----------------------------------------------//
//calculations
//-----------------------------------------------//
up = newmonth ? 100 * ((monthHigh - monthOpen) / monthClose) : na
down = newmonth ? 100 * math.abs(((monthOpen - monthLow) / monthClose)) : na
upStdev = ta.stdev(up, averagingPerdiod) * multiplier
upSD = newmonth ? upStdev[1] : na
downStdev = ta.stdev(down, averagingPerdiod) * multiplier
downSd = newmonth ? downStdev[1] : na

if newmonth
    if upAvgArray.size() > averagingPerdiod
        upAvgArray.pop()
        upAvgArray.unshift(up)
    else
        upAvgArray.unshift(up)
upAvg = upAvgArray.size() > 0 ? upAvgArray.avg() : na

if newmonth
    if downAvgArray.size() > averagingPerdiod
        downAvgArray.pop()
        downAvgArray.unshift(down)
    else
        downAvgArray.unshift(down)
downAvg = downAvgArray.size() > 0 ? downAvgArray.avg() : na
if newmonth
    monthIndex := bar_index

R1 := newmonth ? monthOpen + (upAvg / 100) * monthOpen : R1[1]
R2 := newmonth ? monthOpen + ((upAvg + upSD) / 100) * monthOpen : R2[1]
S1 := newmonth ? monthOpen - (downAvg / 100) * monthOpen : S1[1]
S2 := newmonth ? monthOpen - ((downAvg + downSd) / 100) * monthOpen : S2[1]

//-----------------------------------------------//
//daily stats
//-----------------------------------------------//
monthCount := newmonth ? monthCount + 1 : monthCount
if monthClose > R1
    closeAboveR1 += 1
if monthClose > R2
    closeAboveR2 += 1 
if monthClose < S1
    closeBelowS1 += 1
if monthClose < S2
    closeBelowS2 += 1
if monthHigh >= R1
    touchR1 += 1
if monthHigh >= R2
    touchR2 += 1
if monthLow <= S1
    touchS1 += 1
if monthLow <= S2
    touchS2 += 1
closeInsideAvg = monthCount - closeAboveR1 - closeBelowS1
closeInsideAvgPlus = monthCount - closeAboveR2 - closeBelowS2

//-----------------------------------------------//
//daily stats table
//-----------------------------------------------//
if barstate.islast and showTable and yPos == 'Top' and timeframe.ismonthly
    stats.cell(0,0, ' ')
    stats.cell(0, 1, 'Touch R1: ' + str.tostring(touchR1) + ' / ' + str.tostring((touchR1/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(1, 1, 'Close > R1: ' + str.tostring(closeAboveR1) + ' / ' + str.tostring((closeAboveR1/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(2, 1, 'Touch R2: ' + str.tostring(touchR2) + ' / ' + str.tostring((touchR2/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(3, 1, 'Close > R2: ' + str.tostring(closeAboveR2) + ' / ' + str.tostring((closeAboveR2/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(0, 2, 'Touch S1: ' + str.tostring(touchS1) + ' / ' + str.tostring((touchS1/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(1, 2, 'Close < S1: ' + str.tostring(closeBelowS1) + ' / ' + str.tostring((closeBelowS1/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(2, 2, 'Touch S2: ' + str.tostring(touchS2) + ' / ' + str.tostring((touchS2/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(3, 2, 'Close < S2: ' + str.tostring(closeBelowS2) + ' / ' + str.tostring((closeBelowS2/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(4, 3, 'Months Analyzed: ' + str.tostring(monthCount), text_color = statsText, bgcolor = statsBG)
    stats.cell(4, 1, 'Total Closes Inside R1/S1: ' + str.tostring(closeInsideAvg) + ' / ' + str.tostring((closeInsideAvg/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(4, 2, 'Total Closes Inside R2/S2: ' + str.tostring(closeInsideAvgPlus) +  ' / ' + str.tostring((closeInsideAvgPlus/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
else if barstate.islast and showTable and timeframe.ismonthly
    stats.cell(0, 0, 'Touch R1: ' + str.tostring(touchR1) + ' / ' + str.tostring((touchR1/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(1, 0, 'Close > R1: ' + str.tostring(closeAboveR1) + ' / ' + str.tostring((closeAboveR1/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(2, 0, 'Touch R2: ' + str.tostring(touchR2) + ' / ' + str.tostring((touchR2/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(3, 0, 'Close > R2: ' + str.tostring(closeAboveR2) + ' / ' + str.tostring((closeAboveR2/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(0, 1, 'Touch S1: ' + str.tostring(touchS1) + ' / ' + str.tostring((touchS1/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(1, 1, 'Close < S1: ' + str.tostring(closeBelowS1) + ' / ' + str.tostring((closeBelowS1/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(2, 1, 'Touch S2: ' + str.tostring(touchS2) + ' / ' + str.tostring((touchS2/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(3, 1, 'Close < S2: ' + str.tostring(closeBelowS2) + ' / ' + str.tostring((closeBelowS2/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(0, 2, 'Months Analyzed: ' + str.tostring(monthCount), text_color = statsText, bgcolor = statsBG)
    stats.cell(1, 2, 'Total Closes Inside R1/S1: ' + str.tostring(closeInsideAvg) + ' / ' + str.tostring((closeInsideAvg/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)
    stats.cell(2, 2, 'Total Closes Inside R2/S2: ' + str.tostring(closeInsideAvgPlus) +  ' / ' + str.tostring((closeInsideAvgPlus/monthCount), '#.#%'), 
         text_color = statsText, bgcolor = statsBG)

//-----------------------------------------------//
//support and resistance levels
//-----------------------------------------------//
if newmonth and (syminfo.type == 'stock' or syminfo.type == 'fund' or syminfo.type == 'index')
    (r1Line[1]).delete(), (r2Line[1]).delete(), (s1Line[1]).delete(), (s2Line[1]).delete()
    (r1Label[1]).delete(), (r2Label[1]).delete(), (s1Label[1]).delete(), (s2Label[1]).delete()
    (WO[1]).delete()
    if showWO
        WO := line.new(monthIndex, monthOpen, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((8190/ (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, monthOpen, color = wOColor, width = 3)
    r1Line := line.new(monthIndex, R1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, R1, color = rLineColor, width = 2, style = r1Style.switcher())
    r2Line := line.new(monthIndex, R2, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, R2, color = rLineColor, width = 2, style = r1Style.switcher())
    s1Line := line.new(monthIndex, S1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 :  
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, S1, color = sLineColor, width = 2, style = s1Style.switcher())
    s2Line := line.new(monthIndex, S2, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, S2, color = sLineColor, width = 2, style = s2Style.switcher())
    if showPrice
        r1Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : timeframe.isdaily ? monthIndex + 21 : 
             timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : monthIndex + 21, 
             R1, 'R1 $' + str.tostring(R1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        r2Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : timeframe.isdaily ? monthIndex + 21 : 
             timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : monthIndex + 21, 
             R2, 'R2 $' + str.tostring(R2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        s1Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : timeframe.isdaily ? monthIndex + 21 : 
             timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : monthIndex + 21, 
             S1, 'S1 $' + str.tostring(S1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        s2Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : timeframe.isdaily ? monthIndex + 21 : 
             timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : monthIndex + 21, 
             S2, 'S2 $' + str.tostring(S2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
    if showFill
        (sFill[1]).delete(), (rFill[1]).delete()
        sFill := box.new(monthIndex, S1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 :  
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, S2, border_width = 0, bgcolor = color.new(sLineColor,80))
        rFill := box.new(monthIndex, R1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((8190 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, R2, border_width = 0, bgcolor = color.new(rLineColor,80))
else if newmonth and (syminfo.type == 'crypto' or syminfo.type == 'forex')
    (r1Line[1]).delete(), (r2Line[1]).delete(), (s1Line[1]).delete(), (s2Line[1]).delete()
    (r1Label[1]).delete(), (r2Label[1]).delete(), (s1Label[1]).delete(), (s2Label[1]).delete()
    (WO[1]).delete()
    if showWO
        WO := line.new(monthIndex, monthOpen, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 :
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 30, monthOpen, color = wOColor, width = 3)
    r1Line := line.new(monthIndex, R1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 :
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 30, R1, color = rLineColor, width = 2, style = r1Style.switcher())
    r2Line := line.new(monthIndex, R2, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 30, R2, color = rLineColor, width = 2, style = r2Style.switcher())
    s1Line := line.new(monthIndex, S1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 30, S1, color = sLineColor, width = 2, style = s1Style.switcher())
    s2Line := line.new(monthIndex, S2, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 30, S2, color = sLineColor, width = 2, style = s2Style.switcher())
    if showPrice
        r1Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : monthIndex + 30, 
             R1, 'R1 $' + str.tostring(R1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        r2Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : monthIndex + 30, 
             R2, 'R2 $' + str.tostring(R2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        s1Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : monthIndex + 30, 
             S1, 'S1 $' + str.tostring(S1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        s2Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : monthIndex + 30, 
             S2, 'S2 $' + str.tostring(S2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
    if showFill
        (sFill[1]).delete(), (rFill[1]).delete()
        sFill := box.new(monthIndex, S1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 30, S2, border_width = 0, bgcolor = color.new(sLineColor,80))
        rFill := box.new(monthIndex, R1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 30 : timeframe.isminutes ? monthIndex + int((43200 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 30, R2, border_width = 0, bgcolor = color.new(rLineColor,80))
else if newmonth and syminfo.type == 'cfd'
    (r1Line[1]).delete(), (r2Line[1]).delete(), (s1Line[1]).delete(), (s2Line[1]).delete()
    (r1Label[1]).delete(), (r2Label[1]).delete(), (s1Label[1]).delete(), (s2Label[1]).delete()
    (WO[1]).delete()
    if showWO
        WO := line.new(monthIndex, monthOpen, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 :
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, monthOpen, color = wOColor, width = 3)
    r1Line := line.new(monthIndex, R1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 :
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, R1, color = rLineColor, width = 2, style = r1Style.switcher())
    r2Line := line.new(monthIndex, R2, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, R2, color = rLineColor, width = 2, style = r2Style.switcher())
    s1Line := line.new(monthIndex, S1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, S1, color = sLineColor, width = 2, style = s1Style.switcher())
    s2Line := line.new(monthIndex, S2, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, S2, color = sLineColor, width = 2, style = s2Style.switcher())
    if showPrice
        r1Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : monthIndex + 21, 
             R1, 'R1 $' + str.tostring(R1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        r2Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : monthIndex + 21, 
             R2, 'R2 $' + str.tostring(R2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        s1Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : monthIndex + 21, 
             S1, 'S1 $' + str.tostring(S1, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
        s2Label := label.new(timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : monthIndex + 21, 
             S2, 'S2 $' + str.tostring(S2, format.mintick), style = label.style_label_left, color = color.new(color.white,100),
             textcolor = labelTextColor)
    if showFill
        (sFill[1]).delete(), (rFill[1]).delete()
        sFill := box.new(monthIndex, S1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, S2, border_width = 0, bgcolor = color.new(sLineColor,80))
        rFill := box.new(monthIndex, R1, timeframe.ismonthly ? monthIndex + 2 : timeframe.isweekly ? monthIndex + 5 : 
             timeframe.isdaily ? monthIndex + 21 : timeframe.isminutes ? monthIndex + int((30600 / (str.tonumber(timeframe.period)))) : 
             monthIndex + 21, R2, border_width = 0, bgcolor = color.new(rLineColor,80))
if showPrevious and showFill
    sFill.set_left(bar_index), rFill.set_left(bar_index)

//-----------------------------------------------//
//show historical levels
//-----------------------------------------------//
fillColor = color.new(color.white,100)
r1Plot = plot(showPrevious ? R1 : na, color = color.rgb(253, 0, 0))
r2Plot = plot(showPrevious ? R2 : na, color = color.rgb(90, 0, 0))
s1Plot = plot(showPrevious ? S1 : na, color = color.rgb(0, 174, 255))
s2Plot = plot(showPrevious ? S2 : na, color = color.rgb(0, 86, 214))
woPlot = plot(showPrevious ? monthOpen : na, color = wOColor, style = plot.style_linebr)
fill(r1Plot, r2Plot, color = showFill ? color.new(rLineColor, 80) : fillColor)
fill(s1Plot, s2Plot, color = showFill ? color.new(sLineColor, 80) : fillColor)

//-----------------------------------------------//
//alert conditions
//-----------------------------------------------//
crossR1 = ta.crossover(close,R1)
crossR2 = ta.crossover(close,R2)
crossS1 = ta.crossunder(close,S1)
crossS2 = ta.crossunder(close,S2)

alertcondition(crossR1, 'Cross Above R1', 'Price crossing above R1')
alertcondition(crossR2, 'Cross Above R2', 'Price crossing above R2')
alertcondition(crossS1, 'Cross Below S1', 'Price crossing below S1')
alertcondition(crossS2, 'Cross Below S2', 'Price crossing below S2')
