ADR/AWR/AMR Average Daily+Weekly+Monthly Range[Traders Reality]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Created by infernix, peshocore and xtech5192 - stripped down to ADR/AWR/AMR by divinasion
// Please note while the code is open source and you are free to use it however you like - the 'Traders Reality' name is not - ie if you produce derivatives of this 
// source code you are to name those scripts using "Traders Reality", "Pattern Watchers" or any other name that relates to Traders Reality in any way.

//@version=5
indicator('TR ADR/AWR/AMR', overlay=true, max_bars_back=300, max_lines_count=500, max_labels_count=500)

//change ADR line width by editing line.set_width(id=x_line, width=2) below

// Config
adr_offset_input = input.int(group='Label offsets', title='ADR', defval=25, inline='labeloffset1')
adr_offset_input_50 = input.int(group='Label offsets', title='50% ADR', defval=85, inline='labeloffset1')



showADR = input.bool(group='Average Daily Range - ADR', title='Show ADR?', defval=true, inline='adr')
showADR_DO = input.bool(group='Average Daily Range - ADR', title='Use Daily Open (DO) calc?', defval=false, inline='adr', tooltip='Measure the ADR from the daily open. This will make the ADR static throughout the day. ADR is usually measured taking today high and low. Since todays high and low will change throughout the day, some might prefer to have a static range instead.')
showADRLabels = input.bool(group='Average Daily Range - ADR', title='Labels?', defval=true, inline='adr1')
showADRRange = input.bool(group='Average Daily Range - ADR', title='Range label?', defval=false, inline='adr1')
showADR_50 = input.bool(group='Average Daily Range - ADR', title='Show 50% ADR?', defval=false, inline='adr1')
aDRRange = input.int(group='Average Daily Range - ADR', title='ADR length (days)?', defval=14, minval=1, maxval=31, step=1, inline='adr2', tooltip="Defaults taken from mt4. This defines how many days back to take into consideration when calculating the ADR")
adrColor = input.color(group='Average Daily Range - ADR', title='ADR Color', defval=color.new(color.silver, 50), inline='adr3')
string adrStyleX = input.string(group='Average Daily Range - ADR', defval='Dotted', title='ADR Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='adr3')
adrStyle = adrStyleX == 'Dotted' ? line.style_dotted : (adrStyleX == 'Dashed' ? line.style_dashed : (adrStyleX == 'Solid' ? line.style_solid : line.style_dotted))

showAWR = input.bool(group='Average Weekly Range - AWR', title='Show AWR?', defval=false, inline='awr')
showAWR_WO = input.bool(group='Average Weekly Range - AWR', title='Use Weekly Open (WO) calc?', defval=false, inline='awr', tooltip='Measure the AWR from the weekly open. This will make the AWR static throughout the week. AWR is usually measured taking this weeks high and low. Since this weeks high and low will change throughout the week, some might prefer to have a static range instead.')
showAWRLabels = input.bool(group='Average Weekly Range - AWR', title='Labels?', defval=true, inline='awr1')
showAWRRange = input.bool(group='Average Weekly Range - AWR', title='Range label?', defval=false, inline='awr1')
showAWR_50 = input.bool(group='Average Weekly Range - AWR', title='Show 50% AWR?', defval=false, inline='awr1')
aWRRange = input.int(group='Average Weekly Range - AWR', title='AWR length (weeks)?', defval=4, minval=1, maxval=52, step=1, inline='awr2', tooltip="Defaults taken from mt4. This defines how many weeks back to take into consideration when calculating the AWR")
awrColor = input.color(group='Average Weekly Range - AWR', title='AWR Color', defval=color.new(color.orange, 50), inline='awr3')
string awrStyleX = input.string(group='Average Weekly Range - AWR', defval='Dotted', title='AWR Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='awr3')
awrStyle = awrStyleX == 'Dotted' ? line.style_dotted : (awrStyleX == 'Dashed' ? line.style_dashed : (awrStyleX == 'Solid' ? line.style_solid : line.style_dotted))


showAMR = input.bool(group='Average Monthly Range - AMR', title='Show AMR?', defval=false, inline='amr')
showAMR_MO = input.bool(group='Average Monthly Range - AMR', title='Use Monthly Open (MO) calc?', defval=false, inline='amr',tooltip='Measure the AMR from the monthly open. This will make the AMR static throughout the month. AMR is usually measured taking this months high and low. Since this months high and low will change throughout the month, some might prefer to have a static range instead.')
showAMRLabels = input.bool(group='Average Monthly Range - AMR', title='Labels?', defval=true, inline='amr1')
showAMRRange = input.bool(group='Average Monthly Range - AMR', title='Range label?', defval=false, inline='amr1')
showAMR_50 = input.bool(group='Average Monthly Range - AMR', title='Show 50% AMR?', defval=false, inline='amr1')
aMRRange = input.int(group='Average Monthly Range - AMR', title='AMR length (months)?', defval=6, minval=1, maxval=12, step=1, inline='amr2', tooltip="Defaults taken from mt4. This defines how many months back to take into consideration when calculating the AMR")
amrColor = input.color(group='Average Monthly Range - AMR', title='AMR Color', defval=color.new(color.red, 50), inline='amr3')
string amrStyleX = input.string(group='Average Monthly Range - AMR', defval='Dotted', title='AMR Line Style', options=['Dotted', 'Dashed', 'Solid'], inline='amr3')
amrStyle = amrStyleX == 'Dotted' ? line.style_dotted : (amrStyleX == 'Dashed' ? line.style_dashed : (amrStyleX == 'Solid' ? line.style_solid : line.style_dotted))


showAdrTable = input.bool(group='ADR/ADRx3/AWR/AMR Table', title='Show ADR Table', inline='adrt', defval=true)
showAdrPips = input.bool(group='ADR/ADRx3/AWR/AMR Table', title='Show ADR PIPS', inline='adrt', defval=true) and showAdrTable
showAdrCurrency = input.bool(group='ADR/ADRx3/AWR/AMR Table', title='Show ADR Currency', inline='adrt', defval=false) and showAdrTable
choiceAdrTable = input.string(group='ADR/ADRx3/AWR/AMR Table', title='ADR Table postion', inline='adrt', defval='top_right', options=['top_right', 'top_left', 'top_center', 'bottom_right', 'bottom_left', 'bottom_center'])
adrTableBgColor = input.color(group='ADR/ADRx3/AWR/AMR Table', title='ADR Table: Background Color', inline='adrtc', defval=color.rgb(93, 96, 107, 70))
adrTableTxtColor = input.color(group='ADR/ADRx3/AWR/AMR Table', title='Text Color', inline='adrtc', defval=color.rgb(31, 188, 211, 0))




//Non repainting security
f_security(_symbol, _res, _src, _repaint) =>
    request.security(_symbol, _res, _src[_repaint ? 0 : barstate.isrealtime ? 1 : 0])[_repaint ? 0 : barstate.isrealtime ? 0 : 1]


// Basic vars (needed in functions)

// Only render intraday
validTimeFrame = timeframe.isintraday == true

// Functions
// new_bar: check if we're on a new bar within the session in a given resolution
new_bar(res) =>
    ta.change(time(res)) != 0

// adr: Calculate average daily range for a given length
adr(length, barsBack) =>
    // This is effectively an atr, which is what is used in MT4 to get those levels. FWIW, true range can be also calculated with tr(true)
    trueRange = na(high[1]) ? high - low : math.max(math.max(high - low, math.abs(high - close[1])), math.abs(low - close[1]))
    // Switched to SMA from RMA because somehow it matches MT4 better
    ta.sma(trueRange[barsBack], length)
    
    

// adr_high: Calculate the ADR high given an ADR
adr_high(adr, from_do) =>
    retVal = 0.0
    if not from_do
        retVal := high - low < adr ? low + adr : close >= open ? low + adr : high
    else
        retVal := open + adr
    retVal

// adr_low: Calculate the ADR low given an ADR
adr_low(adr, from_do) =>
    retVal = 0.0
    if not from_do
        retVal := high - low < adr ? high - adr : close >= open ? low : high - adr
    else
        retVal := open - adr
    retVal
    
    

// to_pips: Convert to pips
to_pips(val) =>
    pipSizeCalc = syminfo.mintick * (syminfo.type == "forex" ? 10 : 1)
    returnVal = val/pipSizeCalc
    returnVal
    

adr_label_x_offset = time_close + adr_offset_input * timeframe.multiplier * 60 * 1000
adr_label_x_offset_50 = time_close + adr_offset_input_50 * timeframe.multiplier * 60 * 1000


//Right_Label
r_label_offset(ry, rtext, rstyle, rcolor, valid, labelOffset) =>
    if valid and barstate.isrealtime
        rLabel = label.new(x=labelOffset, y=ry, text=rtext, xloc=xloc.bar_time, style=rstyle, textcolor=rcolor, textalign=text.align_right)
        label.delete(rLabel[1])

draw_line(x_series, res, tag, xColor, xStyle, xWidth, xExtend, isLabelValid, xLabelOffset) =>
    var line x_line = na

    if validTimeFrame and new_bar(res) //and barstate.isnew
        x_line := line.new(bar_index, x_series, bar_index+1, x_series, extend=xExtend, color=xColor, style=xStyle, width=xWidth)
        line.set_width(id=x_line, width=1)
        line.delete(x_line[1])

    if not na(x_line) and not new_bar(res)//and line.get_x2(x_line) != bar_index
        line.set_x2(x_line, bar_index)
        line.set_y1(x_line,x_series)
        line.set_y2(x_line,x_series)

    if isLabelValid  //showADRLabels and validTimeFrame
        x_label = label.new(xLabelOffset, x_series, tag, xloc=xloc.bar_time, style=label.style_none, textcolor=xColor)
        label.delete(x_label[1])


        

//    if isLabelValid  //showADRLabels and validTimeFrame
//        pivot_label = label.new(pivot_label_x_offset, pivot_level, tag, xloc=xloc.bar_time, style=label.style_none, textcolor=pivotLabelColor, textalign=text.align_right)

//        label.delete(pivot_label[1])
//    if not barstate.islast
//        line.set_x2(pivot_line, x=bar_index)
//    else
//        line.set_xloc(pivot_line, levelsstart, time_close + 1 * 86400000, xloc=xloc.bar_time)
//   pivot_line
    





// Get Daily price data
dayHigh = f_security(syminfo.tickerid, 'D', high, false)
dayLow = f_security(syminfo.tickerid, 'D', low, false)
dayOpen = f_security(syminfo.tickerid, 'D', open, false)
dayClose = f_security(syminfo.tickerid, 'D', close, false)


//ADR
// Daily ADR

day_adr = request.security(syminfo.tickerid, 'D', adr(aDRRange,1), lookahead=barmerge.lookahead_on)
day_adr_high = request.security(syminfo.tickerid, 'D', showADR_DO ? adr_high(day_adr, true) : adr_high(day_adr, false), lookahead=barmerge.lookahead_on)
day_adr_low = request.security(syminfo.tickerid, 'D',  showADR_DO ? adr_low(day_adr, true) : adr_low(day_adr, false), lookahead=barmerge.lookahead_on)
day_adr_high_50 = day_adr_high - (day_adr/2)
day_adr_low_50 = day_adr_low + (day_adr/2)
    
if showADR
    string hl = 'Hi-ADR'+ (showADR_DO?'(DO)':'')
    string ll = 'Lo-ADR'+ (showADR_DO?'(DO)':'')
    draw_line(day_adr_high, 'D', hl, adrColor, adrStyle, 2, extend.right, showADRLabels and validTimeFrame, adr_label_x_offset)
    draw_line(day_adr_low, 'D', ll, adrColor, adrStyle, 2, extend.right, showADRLabels and validTimeFrame, adr_label_x_offset)
    r_label_offset((day_adr_high + day_adr_low) / 2, 'ADR ' + str.format('{0,number,#.##}', to_pips(day_adr)) + 'PIPS|' + str.tostring(day_adr, format.mintick) + syminfo.currency, label.style_none, adrColor, showADRLabels and validTimeFrame and showADRRange, adr_label_x_offset)  //ry, rtext, rstyle, rcolor, valid

if showADR and showADR_50
    string hl = '50% Hi-ADR'+ (showADR_DO?'(DO)':'')
    string ll = '50% Lo-ADR'+ (showADR_DO?'(DO)':'')
    draw_line(day_adr_high_50, 'D', hl, adrColor, adrStyle, 2, extend.right, showADRLabels and validTimeFrame, adr_label_x_offset_50)
    draw_line(day_adr_low_50, 'D', ll, adrColor, adrStyle, 2, extend.right, showADRLabels and validTimeFrame, adr_label_x_offset_50)
    r_label_offset((day_adr_high_50 + day_adr_low_50) / 2, '50% ADR ' + str.format('{0,number,#.##}', to_pips(day_adr/2)) + 'PIPS|' + str.tostring(day_adr/2, format.mintick) + syminfo.currency, label.style_none, adrColor, showADRLabels and validTimeFrame and showADRRange, adr_label_x_offset_50)  //ry, rtext, rstyle, rcolor, valid
    
alertcondition(close >= day_adr_high and day_adr_high != 0.0 , "ADR High reached", "PA has reached the calculated ADR High")
alertcondition(close <= day_adr_low and day_adr_low != 0.0 , "ADR Low reached", "PA has reached the calculated ADR Low")
alertcondition(close >= day_adr_high_50 and day_adr_high_50 != 0.0 , "50% of ADR High reached", "PA has reached 50% of the calculated ADR High")
alertcondition(close <= day_adr_low_50 and day_adr_low_50 != 0.0 , "50% ADR Low reached", "PA has reached 50% the calculated ADR Low")


//Weekly ADR    
week_adr = request.security(syminfo.tickerid, 'W', adr(aWRRange,1), lookahead=barmerge.lookahead_on)
week_adr_high = request.security(syminfo.tickerid, 'W', showAWR_WO ? adr_high(week_adr, true) : adr_high(week_adr, false), lookahead=barmerge.lookahead_on)
week_adr_low = request.security(syminfo.tickerid, 'W', showAWR_WO ?  adr_low(week_adr, true) : adr_low(week_adr, false), lookahead=barmerge.lookahead_on)
week_adr_high_50 = week_adr_high - (week_adr/2)
week_adr_low_50 = week_adr_low + (week_adr/2)

if showAWR
    string hl = 'Hi-AWR'+ (showAWR_WO?'(WO)':'')
    string ll = 'Lo-AWR'+ (showAWR_WO?'(WO)':'')
    draw_line(week_adr_high, 'W', hl, awrColor, awrStyle, 1, extend.right, showAWRLabels and validTimeFrame, adr_label_x_offset)
    draw_line(week_adr_low, 'W', ll, awrColor, awrStyle, 1, extend.right, showAWRLabels and validTimeFrame, adr_label_x_offset)
    r_label_offset((week_adr_high + week_adr_low) / 2, 'AWR ' + str.format('{0,number,#.##}', to_pips(week_adr)) + 'PIPS|' + str.tostring(week_adr, format.mintick) + syminfo.currency, label.style_none, awrColor, showAWRLabels and validTimeFrame and showAWRRange, adr_label_x_offset)  //ry, rtext, rstyle, rcolor, valid
if showAWR and showAWR_50
    string hl = '50% Hi-AWR'+ (showAWR_WO?'(WO)':'')
    string ll = '50% Lo-AWR'+ (showAWR_WO?'(WO)':'')
    draw_line(week_adr_high_50, 'W', hl, awrColor, awrStyle, 1, extend.right, showAWRLabels and validTimeFrame, adr_label_x_offset_50)
    draw_line(week_adr_low_50, 'W', ll, awrColor, awrStyle, 1, extend.right, showAWRLabels and validTimeFrame, adr_label_x_offset_50)
    r_label_offset((week_adr_high_50 + week_adr_low_50) / 2, '50% AWR ' + str.format('{0,number,#.##}', to_pips(week_adr/2)) + 'PIPS|' + str.tostring(week_adr/2, format.mintick) + syminfo.currency, label.style_none, awrColor, showAWRLabels and validTimeFrame and showAWRRange, adr_label_x_offset_50)  //ry, rtext, rstyle, rcolor, valid

alertcondition(close >= week_adr_high and week_adr_high != 0 , "AWR High reached", "PA has reached the calculated AWR High")
alertcondition(close <= week_adr_low and week_adr_low != 0 , "AWR Low reached", "PA has reached the calculated AWR Low")
alertcondition(close >= week_adr_high_50 and week_adr_high_50 != 0 , "50% of AWR High reached", "PA has reached 50% of the calculated AWR High")
alertcondition(close <= week_adr_low_50 and week_adr_low_50 != 0 , "50% AWR Low reached", "PA has reached 50% of the calculated AWR Low")


//Monthly ADR 
month_adr = request.security(syminfo.tickerid, 'M', adr(aMRRange,1), lookahead=barmerge.lookahead_on)
month_adr_high = request.security(syminfo.tickerid, 'M', showAMR_MO ? adr_high(month_adr, true) : adr_high(month_adr, false), lookahead=barmerge.lookahead_on)
month_adr_low = request.security(syminfo.tickerid, 'M', showAMR_MO ? adr_low(month_adr, true) : adr_low(month_adr, false), lookahead=barmerge.lookahead_on)
month_adr_high_50 = month_adr_high - (month_adr/2)
month_adr_low_50 = month_adr_low + (month_adr/2)

if showAMR and timeframe.isminutes and timeframe.multiplier >= 3
    string hl = 'Hi-AMR'+ (showAMR_MO?'(MO)':'')
    string ll = 'Lo-AMR'+ (showAMR_MO?'(MO)':'')
    draw_line(month_adr_high, 'M', hl, amrColor, amrStyle, 1, extend.right, showAMRLabels and validTimeFrame, adr_label_x_offset)
    draw_line(month_adr_low, 'M', ll, amrColor, amrStyle, 1, extend.right, showAMRLabels and validTimeFrame, adr_label_x_offset)
    r_label_offset((month_adr_high + month_adr_low) / 2, 'AMR ' + str.format('{0,number,#.##}', to_pips(month_adr)) + 'PIPS|' + str.tostring(month_adr, format.mintick) + syminfo.currency, label.style_none, amrColor, showAMRLabels and validTimeFrame and showAMRRange,adr_label_x_offset)  //ry, rtext, rstyle, rcolor, valid
if showAMR and showAMR_50 and timeframe.isminutes and timeframe.multiplier >= 3
    string hl = '50% Hi-AMR'+ (showAMR_MO?'(MO)':'')
    string ll = '50% Lo-AMR'+ (showAMR_MO?'(MO)':'')
    draw_line(month_adr_high_50, 'M', hl, amrColor, amrStyle, 1, extend.right, showAMRLabels and validTimeFrame, adr_label_x_offset_50)
    draw_line(month_adr_low_50, 'M', ll, amrColor, amrStyle, 1, extend.right, showAMRLabels and validTimeFrame, adr_label_x_offset_50)
    r_label_offset((month_adr_high_50 + month_adr_low_50) / 2, '50% AMR ' + str.format('{0,number,#.##}', to_pips(month_adr/2)) + 'PIPS|' + str.tostring(month_adr/2, format.mintick) + syminfo.currency, label.style_none, amrColor, showAMRLabels and validTimeFrame and showAMRRange,adr_label_x_offset_50)  //ry, rtext, rstyle, rcolor, valid

alertcondition(close >= month_adr_high and month_adr_high != 0 , "AMR High reached", "PA has reached the calculated AMR High")
alertcondition(close <= month_adr_low and month_adr_low != 0 , "AMR Low reached", "PA has reached the calculated AMR Low")
alertcondition(close >= month_adr_high_50 and month_adr_high_50 != 0 , "50% of AMR High reached", "PA has reached 50% of the calculated AMR High")
alertcondition(close <= month_adr_low_50 and month_adr_low_50 != 0 , "50% of AMR Low reached", "PA has reached 50% of the calculated AMR Low")







if barstate.islast and showAdrTable and validTimeFrame

    if showAdrPips or showAdrCurrency
        var table panel = table.new(choiceAdrTable, 2, 16, bgcolor=adrTableBgColor)
        // Table header.
        table.cell(panel, 0, 0, '')
        table.cell(panel, 1, 0, '')
        
        if showAdrPips
            table.cell(panel, 0, 2, 'ADR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 2, str.format('{0,number,#.##}', to_pips(day_adr)) + "PIPS" , text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 3, 'ADRx3', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 3, str.format('{0,number,#.##}', to_pips(day_adr) * 3)+ "PIPS", text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 4, 'AWR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 4, str.format('{0,number,#.##}', to_pips(week_adr)) + "PIPS", text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 5, 'AMR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 5, str.format('{0,number,#.##}', to_pips(month_adr)) + "PIPS", text_color=adrTableTxtColor, text_halign=text.align_left)
        
        if showAdrCurrency  
            table.cell(panel, 0, 6, 'ADR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 6, str.tostring(day_adr, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 7, 'ADRx3', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 7, str.tostring(day_adr * 3, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 8, 'AWR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 8, str.tostring(week_adr, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 0, 9, 'AMR', text_color=adrTableTxtColor, text_halign=text.align_left)
            table.cell(panel, 1, 9, str.tostring(month_adr, format.mintick) + syminfo.currency, text_color=adrTableTxtColor, text_halign=text.align_left)
        


