High/Low of week: Stats & Day of Week tendencies
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/

// High of week day and low of week day statistics
// 'meta averages' showing HoW/LoW day averages across set of all possible custom week start/end days to filter out 'continuation bias' in seeking statistical evidence of day of week tendencies
// August 3rd 2023

// © twingall

//@version=5

indicator("High/Low of week: DAY of week; STATS", overlay=true, max_lines_count =500)

useCustomStart =input.bool(false, "Use custom week start day:", group = "Week Start", inline = '1')
_inputWkStrtDay = input.string("MON", "", group = "Week Start", options = ["MON","TUES","WEDS","THURS","FRI", "SAT", "SUN"], inline = '1', tooltip = "Choose arbitrary start day of week.\n\nUseful for teasing out the week-start/ week-end bias in the stats.\n\nAlso use this setting to skip over bank holiday weeks: if your input day was a bank holiday, its week is discounted from the stats ")
showMetaAverages = input.bool(true, "Show Meta Averages", group = "Week Start", inline ='2', tooltip = "Shows the average frequencies/percentages across the set of all possible custom defined week start days.\n\nThis is an experimental attempt to negate the 'continuation bias' effect that comes from having a hard-defined week start/end time. Make of the results what you will.")

showVerTable = input.bool(true, "Verification Table", group ="~~~ Verification  ~~~",inline = '0')
showNewWeekLines = input.bool(true, "Show New Week Lines:", group = "~~~ Verification  ~~~", inline ='0')
lineCount = input.int(10, "",group = "~~~ Verification  ~~~", inline ='0')
tablePosVer=input.string(position.top_right, "Table position:", options = [position.top_left, position.top_center, position.top_right, position.middle_left, position.middle_center, position.middle_right, position.bottom_left, position.bottom_center, position.bottom_right], group="~~~ Verification  ~~~", inline = '1')

textSizeVer = input.string(size.normal, "Size:", options = [size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group="~~~ Verification  ~~~", inline = '1')
textColVer = input.color(color.blue, "Text color", group="~~~ Verification  ~~~", inline = '2')
borderColVer = input.color(color.blue, "Border color", group="~~~ Verification  ~~~", inline = '2')
_userTimezone = input.string("America/New_York", "(tweak timezone in case of misaligned days)", group ="~~~ Verification  ~~~", inline ='3', options =["America/New_York", "syminfo.timezone", "UTC-10", "UTC-9", "UTC-8", "UTC-7", "UTC-6", "UTC-5", "UTC-4", "UTC-3",
     "UTC-2", "UTC-1","UTC", "UTC+1", "UTC+2", "UTC+3", "UTC+4","UTC+5","UTC+6","UTC+7","UTC+8","UTC+9","UTC+10","UTC+11","UTC+12","UTC+13"], tooltip = "Recommend leaving this as 'America/New_York' regardless of your timezone or your asset\n\nHowever, if you do encounter misaligned day values in the verification table, adjust this to fix..")
showStatsTable = input.bool(true, "show |", group="~~~~ Statistics Table ~~~~", inline = '1')
tablePos = input.string(position.bottom_right, "Table position:", options = [position.top_left, position.top_center, position.top_right, position.middle_left, position.middle_center, position.middle_right, position.bottom_left, position.bottom_center, position.bottom_right], group="~~~~ Statistics Table ~~~~", inline = '1')
textSize = input.string(size.large, "Size:", options = [size.auto, size.tiny, size.small, size.normal, size.large, size.huge], group="~~~~ Statistics Table ~~~~", inline = '1')
textCol = input.color(color.blue, "Text color:", group="~~~~ Statistics Table ~~~~", inline = '2')
borderCol = input.color(color.blue, "Border color:", group="~~~~ Statistics Table ~~~~", inline = '2')

useStartDate = input.bool(false, "use start date | ", inline = "1", group = "~~  Manual Backtesting Period ~~")
startLineCol = input.color(color.red, "start line color", inline = "1", group = "~~  Manual Backtesting Period ~~", tooltip = "this line can be set manually here, or dragged across the chart to change")
startLineWidth = input.int(2, "width", options= [1,2,3,4,5], inline = "1", group = "~~  Manual Backtesting Period ~~")
startDate= input.time(timestamp("20 May 2023 00:00 +0300"), "Start Date", inline = "2", confirm = false, group = "~~  Manual Backtesting Period ~~")

useEndDate = input.bool(false, "use end date | ", inline = "3", group = "~~  Manual Backtesting Period ~~")
endLineCol = input.color(color.blue, "end line color", inline = "3", group = "~~  Manual Backtesting Period ~~", tooltip = "this line can be set manually here, or dragged across the chart to change")
endLineWidth = input.int(2, "width", options= [1,2,3,4,5], inline = "3", group = "~~  Manual Backtesting Period ~~")
endDate= input.time(timestamp("20 Jul 2023 00:00 +0300"), "End Date", inline = "4", confirm = false, group = "~~  Manual Backtesting Period ~~")

    /// Declaring Variables:
var line lnStrt = na
var line lnEnd = na
var int lastWeekLength =na
var float HoWval = na
var float LoWval = na
var int HoWdayInt = na    
var int LoWdayInt = na   

var array<int> HoWArr = array.new<int>(8,0) // need to be size 8 because i don't want to use the '0' element (dayofweek numbers are 1 >> 7)
var array<int> LoWArr = array.new<int>(8,0)
var int H_intLst=na
var int L_intLst=na
var int cusStTime = na
var int cusEndTime = na

var line vLine = na
var array<line> vLineArr = array.new<line>(na)
        // for meta averages:
var array<int> HoWArrMon = array.new<int>(8,0) , var array<int> LoWArrMon = array.new<int>(8,0)
var int HoWdayIntMon = na, var int LoWdayIntMon = na, var int H_intLstMon=na, var int L_intLstMon=na, var int lastWeekLengthMon =na
var array<int> HoWArrTue = array.new<int>(8,0), var array<int> LoWArrTue = array.new<int>(8,0)
var int HoWdayIntTue = na, var int LoWdayIntTue = na, var int H_intLstTue=na, var int L_intLstTue=na, var int lastWeekLengthTue =na
var array<int> HoWArrWed = array.new<int>(8,0), var array<int> LoWArrWed = array.new<int>(8,0)
var int HoWdayIntWed = na, var int LoWdayIntWed = na, var int H_intLstWed=na, var int L_intLstWed=na, var int lastWeekLengthWed =na
var array<int> HoWArrThu = array.new<int>(8,0), var array<int> LoWArrThu = array.new<int>(8,0)
var int HoWdayIntThu = na, var int LoWdayIntThu = na, var int H_intLstThu=na, var int L_intLstThu=na, var int lastWeekLengthThu =na
var array<int> HoWArrFri = array.new<int>(8,0), var array<int> LoWArrFri = array.new<int>(8,0)
var int HoWdayIntFri = na, var int LoWdayIntFri = na, var int H_intLstFri=na, var int L_intLstFri=na, var int lastWeekLengthFri =na
var array<int> HoWArrSat = array.new<int>(8,0), var array<int> LoWArrSat = array.new<int>(8,0)
var int HoWdayIntSat = na, var int LoWdayIntSat = na, var int H_intLstSat=na, var int L_intLstSat=na, var int lastWeekLengthSat =na
var array<int> HoWArrSun = array.new<int>(8,0), var array<int> LoWArrSun = array.new<int>(8,0)
var int HoWdayIntSun = na, var int LoWdayIntSun = na, var int H_intLstSun=na, var int L_intLstSun=na, var int lastWeekLengthSun =na

var VerTable = table.new(tablePosVer, columns = 26, rows = 12, border_width = 1,border_color= borderColVer)
var Table = table.new(tablePos, columns = 9, rows = 16, border_width = 1,border_color= borderCol)


//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''|
//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''|
//    ~~~~~~~~~~~~~~~~    FUNCTIONS    ~~~~~~~~~~~~~~~~
wkStartAndEnd(int _lastWeekLength)=>
    int wkStartTime = na
    int wkEndTime = na
    if _lastWeekLength<8
        wkStartTime:=time[_lastWeekLength]
        wkEndTime := time_close[1]
    if useCustomStart and _lastWeekLength==9 
        wkStartTime:=time[9]
        wkEndTime := time_close[5]
    if useCustomStart and _lastWeekLength==13
        wkStartTime:=time[13]
        wkEndTime := time_close[9]
    [wkStartTime, wkEndTime]

HiLoValAndDoW(bool isHigh, int _lastWeekLength, bool metAvgs)=>
    _hilo = isHigh?high:low
    array<float> HiLoArr = array.new<float>(7) 
    array<int> HiLoTimeArr = array.new<int>(7) /// these should NOT be var, want them to reset on each bar
    if _lastWeekLength<8
        for i = 1 to _lastWeekLength                   
            array.set(HiLoArr, i-1, _hilo[i])   
            array.set(HiLoTimeArr, i-1, time_close[i])    
    if (useCustomStart or metAvgs) and _lastWeekLength==9 // if custom day is missing (bank holiday), count only the prior 'full custom week'
        for i = 1 to 5    
            array.set(HiLoArr, i-1, _hilo[i+4])   
            array.set(HiLoTimeArr, i-1, time_close[i+4])   
    if (useCustomStart or metAvgs)  and _lastWeekLength==13 // for custom day is missing (bank holiday), twice consecutively, count only prior 'full custom week'
        for i = 1 to 5    
            array.set(HiLoArr, i-1, _hilo[i+8])   
            array.set(HiLoTimeArr, i-1, time_close[i+8])    
    hiloVal = isHigh?array.max(HiLoArr):array.min(HiLoArr)
    hiloInd = array.indexof(HiLoArr,hiloVal)            
    whenHiLo = hiloInd!=-1?array.get(HiLoTimeArr, hiloInd):na
    DoWHiLo = dayofweek(whenHiLo, _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone)    
    [hiloVal, DoWHiLo]

pctFxn(array<int> _arr, int _ind)=>
    float result = (array.get(_arr, _ind)/array.sum(_arr))*100

DayCellsFill(int col, int _day)=> 
    table.cell(Table, col, 3, array.get(HoWArr, _day)!=0?str.tostring(array.get(HoWArr, _day)):" -- ", bgcolor =color.new(color.green, 80), text_size = textSize, text_color=textCol, text_halign =text.align_center)
    table.cell(Table, col, 4, array.get(HoWArr, _day)!=0?(str.tostring(pctFxn(HoWArr, _day), '0.0')+"%"):" -- ", bgcolor =color.new(color.green, 80), text_size = textSize, text_color=textCol, text_halign =text.align_center)
    table.cell(Table, col, 5, array.get(LoWArr, _day)!=0?str.tostring(array.get(LoWArr, _day)):" -- ", bgcolor =color.new(color.red, 80), text_size = textSize, text_color=textCol, text_halign =text.align_center)
    table.cell(Table, col, 6, array.get(LoWArr, _day)!=0?(str.tostring(pctFxn(LoWArr, _day), '0.0')+"%"):" -- ", bgcolor =color.new(color.red, 80), text_size = textSize, text_color=textCol, text_halign =text.align_center)

DoW(int num)=> 
    dayofweek(time_close, _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone) == num

DoWstring(int _DoW)=>
    string dayString = switch _DoW
        1 => "Sunday"
        2 => "Monday"
        3 => "Tuesday"
        4 => "Wednesday"
        5 => "Thursday"
        6 => "Friday"
        7 => "Saturday"
        => na

incremMetaAvgs(int H, int L, array<int> arrH, array<int> arrL)=>
    H_intLast = array.get(arrH, H)
    array.set(arrH, H, H_intLast+1)
    L_intLast = array.get(arrL, L)
    array.set(arrL, L, L_intLast+1)

metaAverage(int _day)=>
    if array.get(HoWArr, 1) ==0 and array.get(HoWArr, 7)==0
        MetaAvgHoW= math.round( math.avg( array.get(HoWArrMon, _day), array.get(HoWArrTue, _day), array.get(HoWArrWed, _day), array.get(HoWArrThu, _day), array.get(HoWArrFri, _day)))
        MetaAvgLoW= math.round( math.avg( array.get(LoWArrMon, _day), array.get(LoWArrTue, _day), array.get(LoWArrWed, _day), array.get(LoWArrThu, _day), array.get(LoWArrFri, _day)))
        MetaAvgHoWpct = math.round(math.avg(pctFxn(HoWArrMon, _day), pctFxn(HoWArrTue, _day), pctFxn(HoWArrWed, _day), pctFxn(HoWArrThu, _day), pctFxn(HoWArrFri, _day)),2)
        MetaAvgLoWpct = math.round(math.avg(pctFxn(LoWArrMon, _day), pctFxn(LoWArrTue, _day), pctFxn(LoWArrWed, _day), pctFxn(LoWArrThu, _day), pctFxn(LoWArrFri, _day)),2)
        [MetaAvgHoW, MetaAvgLoW, MetaAvgHoWpct, MetaAvgLoWpct]
    else
        MetaAvgHoW= math.round( math.avg( array.get(HoWArrMon, _day), array.get(HoWArrTue, _day), array.get(HoWArrWed, _day), array.get(HoWArrThu, _day), array.get(HoWArrFri, _day), array.get(HoWArrSat, _day), array.get(HoWArrSun, _day)))
        MetaAvgLoW= math.round( math.avg( array.get(LoWArrMon, _day), array.get(LoWArrTue, _day), array.get(LoWArrWed, _day), array.get(LoWArrThu, _day), array.get(LoWArrFri, _day), array.get(LoWArrSat, _day), array.get(LoWArrSun, _day)))
        MetaAvgHoWpct = math.round(math.avg(pctFxn(HoWArrMon, _day), pctFxn(HoWArrTue, _day), pctFxn(HoWArrWed, _day), pctFxn(HoWArrThu, _day), pctFxn(HoWArrFri, _day), pctFxn(HoWArrSat, _day), pctFxn(HoWArrSun, _day)),2)
        MetaAvgLoWpct = math.round(math.avg(pctFxn(LoWArrMon, _day), pctFxn(LoWArrTue, _day), pctFxn(LoWArrWed, _day), pctFxn(LoWArrThu, _day), pctFxn(LoWArrFri, _day), pctFxn(LoWArrSat, _day), pctFxn(LoWArrSun, _day)),2)
        [MetaAvgHoW, MetaAvgLoW, MetaAvgHoWpct, MetaAvgLoWpct]

metaAvgCellFill(int col, int superDayHoW, int superDayLoW, float superDayHoWpct, float superDayLoWpct)=>
    table.cell(Table, col, 8, superDayHoW!=0?str.tostring(superDayHoW):" -- ", bgcolor =color.new(color.green, 80), text_size = textSize, text_color=textCol, text_halign =text.align_center)
    table.cell(Table, col, 9, superDayHoWpct!=0?(str.tostring(superDayHoWpct, '0.0')+"%"):" -- ", bgcolor =color.new(color.green, 80), text_size = textSize, text_color=textCol, text_halign =text.align_center)
    table.cell(Table, col, 10, superDayLoW!=0?str.tostring(superDayLoW):" -- ", bgcolor =color.new(color.red, 80), text_size = textSize, text_color=textCol, text_halign =text.align_center)
    table.cell(Table, col, 11, superDayLoWpct!=0?(str.tostring(superDayLoWpct, '0.0')+"%"):" -- ", bgcolor =color.new(color.red, 80), text_size = textSize, text_color=textCol, text_halign =text.align_center)

//..........................................................||
//..........................................................||

if barstate.islastconfirmedhistory and useStartDate and timeframe.isdaily
    lnStrt:=line.new(startDate, high, startDate, high+1, xloc = xloc.bar_time, color= startLineCol, extend = extend.both, width = startLineWidth)
    line.delete(lnStrt[1])
if barstate.islastconfirmedhistory and useEndDate and timeframe.isdaily
    lnEnd:=line.new(endDate, high, endDate, high+1, xloc = xloc.bar_time, color= endLineCol, extend = extend.both, width = endLineWidth)
    line.delete(lnEnd[1])
int inputWkStrtDay = switch _inputWkStrtDay
    "SUN" => 1
    "MON" => 2
    "TUES" => 3
    "WEDS" => 4
    "THURS" => 5
    "FRI" => 6
    "SAT" => 7
    =>na
tradNewWeek = timeframe.change('W') 
customNewWeek = dayofweek(time_close, _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone) == inputWkStrtDay // Sun = 1
new_week = useCustomStart?customNewWeek:tradNewWeek 

timeCond = useStartDate and useEndDate? time>startDate and time<endDate: useStartDate and not useEndDate? time>startDate: not useStartDate and useEndDate? time<endDate:true
WeeklengthBarInd = ta.valuewhen(new_week, bar_index, 1)

if new_week and bar_index >10 and timeCond and timeframe.isdaily   
    lastWeekLength:= bar_index- WeeklengthBarInd

[_HoWval, _DoWhi] = HiLoValAndDoW(true, lastWeekLength, false)
[_LoWval, _DoWlo] = HiLoValAndDoW(false, lastWeekLength, false)
[weekStTime, weekEndTime] = wkStartAndEnd(lastWeekLength)

if new_week and bar_index >10 and timeCond and timeframe.isdaily  and (lastWeekLength <8 or lastWeekLength==9 or lastWeekLength==13)
    HoWval:= _HoWval
    LoWval:= _LoWval
    HoWdayInt := _DoWhi
    LoWdayInt := _DoWlo
    H_intLst := array.get(HoWArr, HoWdayInt)  // get last value for that day of week cumulative frequency
    array.set(HoWArr,HoWdayInt, H_intLst+1)   // increment by 1
    L_intLst := array.get(LoWArr, LoWdayInt)
    array.set(LoWArr,LoWdayInt, L_intLst+1)
    cusStTime:= weekStTime
    cusEndTime:=weekEndTime
sumHoWs = array.sum(HoWArr)
sumLoWs = array.sum(LoWArr)

//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''||
//''''''''''''''''''''''''''''''''''''''''''''''''''''''''''||
//    ~~~~~~~~~~~~~~~~ META AVERAGES ~~~~~~~~~~~~~~~~

monStart = DoW(2) 
tueStart = DoW(3)
wedStart = DoW(4) 
thuStart = DoW(5)
friStart = DoW(6) 
satStart = DoW(7)
sunStart = DoW(1) 

WeeklengthBarIndMon = ta.valuewhen(monStart, bar_index, 1)
WeeklengthBarIndTue = ta.valuewhen(tueStart, bar_index, 1)
WeeklengthBarIndWed = ta.valuewhen(wedStart, bar_index, 1)
WeeklengthBarIndThu = ta.valuewhen(thuStart, bar_index, 1)
WeeklengthBarIndFri = ta.valuewhen(friStart, bar_index, 1)
WeeklengthBarIndSat = ta.valuewhen(satStart, bar_index, 1)
WeeklengthBarIndSun = ta.valuewhen(sunStart, bar_index, 1)

if monStart and bar_index >10 and timeCond and timeframe.isdaily and showMetaAverages
    lastWeekLengthMon:= bar_index- WeeklengthBarIndMon 
[_HoWvalMon, _DoWhiMon] = HiLoValAndDoW(true, lastWeekLengthMon, true)
[_LoWvalMon, _DoWloMon] = HiLoValAndDoW(false, lastWeekLengthMon, true)
if monStart and bar_index >10 and timeCond and timeframe.isdaily and (lastWeekLengthMon <8 or lastWeekLengthMon==9 or lastWeekLengthMon==13) and showMetaAverages
    incremMetaAvgs(_DoWhiMon, _DoWloMon, HoWArrMon, LoWArrMon)

if tueStart and bar_index >10 and timeCond and timeframe.isdaily and showMetaAverages  
    lastWeekLengthTue:= bar_index- WeeklengthBarIndTue 
[_HoWvalTue, _DoWhiTue] = HiLoValAndDoW(true, lastWeekLengthTue, true)
[_LoWvalTue, _DoWloTue] = HiLoValAndDoW(false, lastWeekLengthTue, true)
if tueStart and bar_index >10 and timeCond and timeframe.isdaily and (lastWeekLengthTue <8 or lastWeekLengthTue==9 or lastWeekLengthTue==13) and showMetaAverages
    incremMetaAvgs(_DoWhiTue, _DoWloTue, HoWArrTue, LoWArrTue)

if wedStart and bar_index >10 and timeCond and timeframe.isdaily and showMetaAverages 
    lastWeekLengthWed:= bar_index- WeeklengthBarIndWed 
[_HoWvalWed, _DoWhiWed] = HiLoValAndDoW(true, lastWeekLengthWed, true)
[_LoWvalWed, _DoWloWed] = HiLoValAndDoW(false, lastWeekLengthWed, true)
if wedStart and bar_index >10 and timeCond and timeframe.isdaily and (lastWeekLengthWed <8 or lastWeekLengthWed==9 or lastWeekLengthWed==13) and showMetaAverages
    incremMetaAvgs(_DoWhiWed, _DoWloWed, HoWArrWed, LoWArrWed)

if thuStart and bar_index >10 and timeCond and timeframe.isdaily and showMetaAverages  
    lastWeekLengthThu:= bar_index- WeeklengthBarIndThu 
[_HoWvalThu, _DoWhiThu] = HiLoValAndDoW(true, lastWeekLengthThu, true)
[_LoWvalThu, _DoWloThu] = HiLoValAndDoW(false, lastWeekLengthThu, true)
if thuStart and bar_index >10 and timeCond and timeframe.isdaily and (lastWeekLengthThu <8 or lastWeekLengthThu==9 or lastWeekLengthThu==13) and showMetaAverages
    incremMetaAvgs(_DoWhiThu, _DoWloThu, HoWArrThu, LoWArrThu)

if friStart and bar_index >10 and timeCond and timeframe.isdaily and showMetaAverages 
    lastWeekLengthFri:= bar_index- WeeklengthBarIndFri 
[_HoWvalFri, _DoWhiFri] = HiLoValAndDoW(true, lastWeekLengthFri, true)
[_LoWvalFri, _DoWloFri] = HiLoValAndDoW(false, lastWeekLengthFri, true)
if friStart and bar_index >10 and timeCond and timeframe.isdaily and (lastWeekLengthFri <8 or lastWeekLengthFri==9 or lastWeekLengthFri==13) and showMetaAverages
    incremMetaAvgs(_DoWhiFri, _DoWloFri, HoWArrFri, LoWArrFri)

if satStart and bar_index >10 and timeCond and timeframe.isdaily and showMetaAverages
    lastWeekLengthSat:= bar_index- WeeklengthBarIndSat 
[_HoWvalSat, _DoWhiSat] = HiLoValAndDoW(true, lastWeekLengthSat, true)
[_LoWvalSat, _DoWloSat] = HiLoValAndDoW(false, lastWeekLengthSat, true)
if satStart and bar_index >10 and timeCond and timeframe.isdaily and (lastWeekLengthSat <8 or lastWeekLengthSat==9 or lastWeekLengthSat==13) and showMetaAverages
    incremMetaAvgs(_DoWhiSat, _DoWloSat, HoWArrSat, LoWArrSat)

if sunStart and bar_index >10 and timeCond and timeframe.isdaily and showMetaAverages 
    lastWeekLengthSun:= bar_index- WeeklengthBarIndSun 
[_HoWvalSun, _DoWhiSun] = HiLoValAndDoW(true, lastWeekLengthSun, true)
[_LoWvalSun, _DoWloSun] = HiLoValAndDoW(false, lastWeekLengthSun, true)
if sunStart and bar_index >10 and timeCond and timeframe.isdaily and (lastWeekLengthSun <8 or lastWeekLengthSun==9 or lastWeekLengthSun==13) and showMetaAverages
    incremMetaAvgs(_DoWhiSun, _DoWloSun, HoWArrSun, LoWArrSun)

[monMetaAvgHoW, monMetaAvgLoW, monMetaAvgHoWpct, monMetaAvgLoWpct] = metaAverage(2)
[tueMetaAvgHoW, tueMetaAvgLoW, tueMetaAvgHoWpct, tueMetaAvgLoWpct] = metaAverage(3)
[wedMetaAvgHoW, wedMetaAvgLoW, wedMetaAvgHoWpct, wedMetaAvgLoWpct] = metaAverage(4)
[thuMetaAvgHoW, thuMetaAvgLoW, thuMetaAvgHoWpct, thuMetaAvgLoWpct] = metaAverage(5)
[friMetaAvgHoW, friMetaAvgLoW, friMetaAvgHoWpct, friMetaAvgLoWpct] = metaAverage(6)
[satMetaAvgHoW, satMetaAvgLoW, satMetaAvgHoWpct, satMetaAvgLoWpct] = metaAverage(7)
[sunMetaAvgHoW, sunMetaAvgLoW, sunMetaAvgHoWpct, sunMetaAvgLoWpct] = metaAverage(1)

//..........................................................||
//..........................................................||

    // for displaying the start of traditional week & end of traditional week 
[_prevWkOpTime, _prevWkClTime] = request.security(syminfo.tickerid, "W", [time[1], time_close[1]])
PrevWkOpTime = str.format_time(_prevWkOpTime, "HH:mm", _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone)
PrevWkClTime = str.format_time(_prevWkClTime, "HH:mm", _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone)
_PrevWkOpDay = dayofweek(_prevWkOpTime, _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone) 
_PrevWkClDay = dayofweek(_prevWkClTime, _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone) 
PrevWkOpDay = DoWstring(_PrevWkOpDay)
PrevWkClDay = DoWstring(_PrevWkClDay)

    // for displaying start start of custom week & end of custom week
customPrevWkStTime = str.format_time(cusStTime, "HH:mm", _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone)
customPrevWkEndTime = str.format_time(cusEndTime, "HH:mm", _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone)
_customWkStartDay= dayofweek(cusStTime, _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone)   
_customWkEndDay = dayofweek(cusEndTime, _userTimezone=="syminfo.timezone"? syminfo.timezone:_userTimezone)    
customWkStartDay = DoWstring(_customWkStartDay)
customWkEndDay = DoWstring(_customWkEndDay)

HoWday = DoWstring(HoWdayInt)
LoWday = DoWstring(LoWdayInt)

if barstate.islast and timeframe.isdaily and showVerTable
    table.cell(VerTable, 0, 0, "~~ VERIFICATION ~~ (Last Week)",bgcolor =color.new(color.red, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.merge_cells(VerTable, 0, 0, 2, 0)

    table.cell(VerTable,0, 1, "High of week: ", bgcolor =color.new(color.red, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.cell(VerTable, 1, 1, HoWday, bgcolor =color.new(color.red, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.cell(VerTable,2, 1, str.tostring(math.round_to_mintick(HoWval)), bgcolor =color.new(color.red, 50), text_size = textSizeVer, text_color =textCol, text_halign =text.align_center)
    table.cell(VerTable, 0, 2, "Low of week: ", bgcolor =color.new(color.red, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.cell(VerTable, 1, 2, LoWday, bgcolor =color.new(color.red, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.cell(VerTable, 2, 2, str.tostring(math.round_to_mintick(LoWval)), bgcolor =color.new(color.red, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)

    table.cell(VerTable, 0, 3, "last week length (bars): ", bgcolor =color.new(color.gray, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.merge_cells(VerTable, 0, 3, 1, 3)
    table.cell(VerTable, 2, 3, str.tostring(lastWeekLength), bgcolor =color.new(color.gray, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.cell(VerTable, 0, 4, text = useCustomStart? "~~ Custom Week ~~":"~~ Traditional Week ~~", bgcolor =color.new(color.orange, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.merge_cells(VerTable, 0, 4, 2, 4)
    table.cell(VerTable, 0, 5, "Week Start:", bgcolor =color.new(color.orange, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.cell(VerTable, 1, 5, text = useCustomStart?(customWkStartDay+"  "+customPrevWkStTime):(PrevWkOpDay+ "  "+PrevWkOpTime), bgcolor =color.new(color.orange, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.merge_cells(VerTable, 1, 5, 2, 5)
    table.cell(VerTable, 0, 6, "Week End:", bgcolor =color.new(color.orange, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.cell(VerTable, 1, 6, text = useCustomStart?(customWkEndDay+"  "+customPrevWkEndTime):(PrevWkClDay+ "  "+PrevWkClTime), bgcolor =color.new(color.orange, 50), text_size = textSizeVer, text_color =textColVer, text_halign =text.align_center)
    table.merge_cells(VerTable, 1, 6, 2, 6)

if barstate.islast and timeframe.isdaily and showStatsTable 
    if useCustomStart
        table.cell(Table, 1, 0,  "(Custom week start day =  "+_inputWkStrtDay+")", bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
        table.merge_cells(Table, 1, 0, 7, 0)
    table.cell(Table, 1, 1,  "~~ STATISTICS ~~ || Asset =  "+str.tostring(syminfo.ticker), bgcolor =color.new(color.blue, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.merge_cells(Table, 1, 1, 7, 1)
    table.cell(Table, 0, 1,      str.tostring(sumHoWs)+   " = Weeks History\n(" +str.tostring(sumHoWs/52, '#.#')+" yrs)", bgcolor =color.new(color.red, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)   //array.size to be inserted here
    table.cell(Table, 0, 2, "Day of week:" , bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 0, 3, "High of week (freq):" , bgcolor =color.new(color.green, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 0, 4, "High of week (%):" , bgcolor =color.new(color.green, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 0, 5, "Low of week (freq):" , bgcolor =color.new(color.red, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 0, 6, "Low of week (%):" , bgcolor =color.new(color.red, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 1, 2, " MON " , bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 2, 2, "TUES " , bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 3, 2, "WEDS " , bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 4, 2, "THURS" , bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 5, 2, "  FRI  " , bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 6, 2, "  SAT " , bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    table.cell(Table, 7, 2, " SUN " , bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
    DayCellsFill(1,2)
    DayCellsFill(2,3)
    DayCellsFill(3,4)
    DayCellsFill(4,5)
    DayCellsFill(5,6)
    DayCellsFill(6,7)
    DayCellsFill(7,1)

    if showMetaAverages
        table.cell(Table, 0,7, "~~ META AVERAGES: averages from set of all possible custom weeks ~~", bgcolor =color.new(color.yellow, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
        table.merge_cells(Table, 0,7,7,7)
        table.cell(Table, 0, 8, "High of week (freq):" , bgcolor =color.new(color.green, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
        table.cell(Table, 0, 9, "High of week (%):" , bgcolor =color.new(color.green, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
        table.cell(Table, 0, 10, "Low of week (freq):" , bgcolor =color.new(color.red, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
        table.cell(Table, 0, 11, "Low of week (%):" , bgcolor =color.new(color.red, 50), text_size = textSize, text_color =textCol, text_halign =text.align_center)
        metaAvgCellFill(1, monMetaAvgHoW, monMetaAvgLoW, monMetaAvgHoWpct, monMetaAvgLoWpct)
        metaAvgCellFill(2, tueMetaAvgHoW, tueMetaAvgLoW, tueMetaAvgHoWpct, tueMetaAvgLoWpct)
        metaAvgCellFill(3, wedMetaAvgHoW, wedMetaAvgLoW, wedMetaAvgHoWpct, wedMetaAvgLoWpct)
        metaAvgCellFill(4, thuMetaAvgHoW, thuMetaAvgLoW, thuMetaAvgHoWpct, thuMetaAvgLoWpct)
        metaAvgCellFill(5, friMetaAvgHoW, friMetaAvgLoW, friMetaAvgHoWpct, friMetaAvgLoWpct)
        metaAvgCellFill(6, satMetaAvgHoW, satMetaAvgLoW, satMetaAvgHoWpct, satMetaAvgLoWpct)
        metaAvgCellFill(7, sunMetaAvgHoW, sunMetaAvgLoW, sunMetaAvgHoWpct, sunMetaAvgLoWpct)

    //  wrong timeframe warning message
if barstate.islast and not timeframe.isdaily
    table.cell(Table, 1, 0, "!! This indicator only works on Daily timeframe !!" , bgcolor =color.new(color.blue, 50), text_size = size.large, text_color =color.red, text_halign =text.align_center)

    // vertical new week lines
if new_week and showNewWeekLines and timeframe.isdaily 
    vLine:= line.new(bar_index, high, bar_index, high+1, extend=extend.both, style = line.style_dashed)
    array.push(vLineArr, vLine)
    if array.size(vLineArr)>lineCount
        line.delete(array.shift(vLineArr))