season
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © voided

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

type    = input.string("month", options = [ "month", "weekofyear", "dayofmonth", "dayofweek", "hour", "minute"])
labels  = input.bool(false, "labels")
start   = input(1, "start")
end     = input(3, "end")
delta   = end - start + 1
src     = type == "month" ? month : type == "weekofyear" ? weekofyear : type == "dayofmonth" ? dayofmonth : type == "dayofweek" ? dayofweek : type == "hour" ? hour : type == "minute" ? minute : na

highlight = color.new(color.red, 90)
none      = color.new(color.white, 100)

on = src >= start and src <= end

bgcolor(on ? highlight : none)

var sea_sampling  = array.new_float()
var pop_sampling  = array.new_float()

ret = math.log(close / close[1])

if src == end

    sea_rets = array.new_float()
    
    for i = 0 to delta
        
        array.push(sea_rets, ret[i])
    
    array.push(sea_sampling, array.avg(sea_rets))
    
    if labels
    
        label.new(bar_index, high * 1.5, text = str.tostring(ret * 100, "#.##") + "%", style = label.style_none)
        
else

    pop_rets = array.new_float()
    
    for i = 0 to delta
    
        array.push(pop_rets, ret[i])
        
    array.push(pop_sampling, array.avg(pop_rets))


if barstate.islast

    fmt = "#.##"
    
    t = table.new(position.middle_right, 3, 12, bgcolor = color.white)
    
    sea_avg = array.avg(sea_sampling)
    pop_avg = array.avg(pop_sampling)
    
    sea_std = array.stdev(sea_sampling)
    pop_std = array.stdev(pop_sampling)
    
    sea_size = array.size(sea_sampling)
    pop_size = array.size(pop_sampling)
    
    z   = (sea_avg - pop_avg) / (sea_std / math.sqrt(sea_size))
    p05 = z >= -2 and z <= 2 ? color.red : color.green
    p01 = z >= -2.575829 and z <= 2.575829 ? color.red : color.green
    
    lbl_clr = color.new(color.blue, 80)
    
    table.cell(t, 0, 0, bgcolor = lbl_clr)
    table.cell(t, 1, 0, "season", bgcolor = lbl_clr)
    table.cell(t, 2, 0, "population", bgcolor = lbl_clr)
    
    table.cell(t, 0, 1, "samples", bgcolor = lbl_clr)
    table.cell(t, 1, 1, str.tostring(sea_size, fmt))
    table.cell(t, 2, 1, str.tostring(pop_size, fmt))
    
    table.cell(t, 0, 2, "mean", bgcolor = lbl_clr)
    table.cell(t, 1, 2, str.tostring(sea_avg * 100, fmt) + "%")
    table.cell(t, 2, 2, str.tostring(pop_avg * 100, fmt) + "%")

    table.cell(t, 0, 3, "median", bgcolor = lbl_clr)
    table.cell(t, 1, 3, str.tostring(array.median(sea_sampling) * 100, fmt) + "%")
    table.cell(t, 2, 3, str.tostring(array.median(pop_sampling) * 100, fmt) + "%")

    table.cell(t, 0, 4, "stdev", bgcolor = lbl_clr)
    table.cell(t, 1, 4, str.tostring(sea_std * 100, fmt) + "%")
    table.cell(t, 2, 4, str.tostring(pop_std * 100, fmt) + "%")

    table.cell(t, 0, 5, "1%", bgcolor = lbl_clr)
    table.cell(t, 1, 5, str.tostring(array.percentile_nearest_rank(sea_sampling, 1) * 100, fmt) + "%")
    table.cell(t, 2, 5, str.tostring(array.percentile_nearest_rank(pop_sampling, 1) * 100, fmt) + "%")
    
    table.cell(t, 0, 6, "5%", bgcolor = lbl_clr)
    table.cell(t, 1, 6, str.tostring(array.percentile_nearest_rank(sea_sampling, 5) * 100, fmt) + "%")
    table.cell(t, 2, 6, str.tostring(array.percentile_nearest_rank(pop_sampling, 5) * 100, fmt) + "%")

    table.cell(t, 0, 7, "95%", bgcolor = lbl_clr)
    table.cell(t, 1, 7, str.tostring(array.percentile_nearest_rank(sea_sampling, 95) * 100, fmt) + "%")
    table.cell(t, 2, 7, str.tostring(array.percentile_nearest_rank(pop_sampling, 95) * 100, fmt) + "%")

    table.cell(t, 0, 8, "99%", bgcolor = lbl_clr)
    table.cell(t, 1, 8, str.tostring(array.percentile_nearest_rank(sea_sampling, 99) * 100, fmt) + "%")
    table.cell(t, 2, 8, str.tostring(array.percentile_nearest_rank(pop_sampling, 99) * 100, fmt) + "%")

    table.cell(t, 0, 9, "z-test", bgcolor = lbl_clr)
    table.cell(t, 1, 9, str.tostring(z, fmt))
    table.cell(t, 2, 9)
    
    table.cell(t, 0, 10, "significant (p = 0.05)", bgcolor = lbl_clr)
    table.cell(t, 1, 10, bgcolor = p05)
    table.cell(t, 2, 10, bgcolor = p05)
    
    table.cell(t, 0, 11, "significant (p = 0.01)", bgcolor = lbl_clr)
    table.cell(t, 1, 11, bgcolor = p01)
    table.cell(t, 2, 11, bgcolor = p01)
