[SM] Bitcoin cycles bull market
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Strateg_maker

//@version=5
indicator("[SM] Bitcoin cycles bull market", "[SM] Bitcoin cycles", overlay=true)


//======================================================================
//     Seting input
//======================================================================

mode            = input.bool(defval=false, title="Do you have a TW black theme?", group="Color theme")

table_on        = input.bool(defval=true, title="Show the table?", group="Table")
number_month    = input.int(defval=12, title="How many months to show in the table?", group="Table")

time_1m_s       = input.bool(defval=false, title="On/off 1 month Summer", group="Select a period 1 month summer")
day_1m_s_in     = input.int(defval=10, title="Day in begin", group="Select a period 1 month summer", inline="5")
month_1m_s_in   = input.int(defval=07, title="Month in begin", group="Select a period 1 month summer", inline="5")
day_1m_s_in_    = input.int(defval=20, title="Day in end...", group="Select a period 1 month summer", inline="6")
month_1m_s_in_  = input.int(defval=07, title="Month in end...", group="Select a period 1 month summer", inline="6")
day_1m_s_out    = input.int(defval=10, title="Day out begin", group="Select a period 1 month summer", inline="7")
month_1m_s_out  = input.int(defval=08, title="Month out begin", group="Select a period 1 month summer", inline="7")
day_1m_s_out_   = input.int(defval=20, title="Day out end...", group="Select a period 1 month summer", inline="8")
month_1m_s_out_ = input.int(defval=08, title="Month out end...", group="Select a period 1 month summer", inline="8")

time_1m_a       = input.bool(defval=false, title="On/off 1 month Autumn", group="Select a period 1 month autumn")
day_1m_a_in     = input.int(defval=25, title="Day in begin", group="Select a period 1 month autumn", inline="9")
month_1m_a_in   = input.int(defval=09, title="Month in begin", group="Select a period 1 month autumn", inline="9")
day_1m_a_in_    = input.int(defval=05, title="Day in end...", group="Select a period 1 month autumn", inline="10")
month_1m_a_in_  = input.int(defval=10, title="Month in end...", group="Select a period 1 month autumn", inline="10")
day_1m_a_out    = input.int(defval=20, title="Day out begin", group="Select a period 1 month autumn", inline="11")
month_1m_a_out  = input.int(defval=10, title="Month out begin", group="Select a period 1 month autumn", inline="11")
day_1m_a_out_   = input.int(defval=30, title="Day out end...", group="Select a period 1 month autumn", inline="12")
month_1m_a_out_ = input.int(defval=10, title="Month out end...", group="Select a period 1 month autumn", inline="12")

time_1m_w       = input.bool(defval=false, title="On/off 1 month Winter", group="Select a period 1 month winter")
day_1m_w_in     = input.int(defval=01, title="Day in begin", group="Select a period 1 month winter", inline="1")
month_1m_w_in   = input.int(defval=12, title="Month in begin", group="Select a period 1 month winter", inline="1")
day_1m_w_in_    = input.int(defval=31, title="Day in end...", group="Select a period 1 month winter", inline="2")
month_1m_w_in_  = input.int(defval=12, title="Month in end...", group="Select a period 1 month winter", inline="2")
day_1m_w_out    = input.int(defval=01, title="Day out begin", group="Select a period 1 month winter", inline="3")
month_1m_w_out  = input.int(defval=01, title="Month out begin", group="Select a period 1 month winter", inline="3")
day_1m_w_out_   = input.int(defval=10, title="Day out end...", group="Select a period 1 month winter", inline="4")
month_1m_w_out_ = input.int(defval=01, title="Month out end...", group="Select a period 1 month winter", inline="4")

time_3m         = input.bool(defval=false, title="On/off 3 month", group="Select a period 3 month")
day_3m_in       = input.int(defval=01, title="Day in begin", group="Select a period 3 month", inline="13")
month_3m_in     = input.int(defval=03, title="Month in begin", group="Select a period 3 month", inline="13")
day_3m_in_      = input.int(defval=31, title="Day in end...", group="Select a period 3 month", inline="14")
month_3m_in_    = input.int(defval=03, title="Month in end...", group="Select a period 3 month", inline="14")
day_3m_out      = input.int(defval=01, title="Day out begin", group="Select a period 3 month", inline="15")
month_3m_out    = input.int(defval=05, title="Month out begin", group="Select a period 3 month", inline="15")
day_3m_out_     = input.int(defval=30, title="Day out end...", group="Select a period 3 month", inline="16")
month_3m_out_   = input.int(defval=05, title="Month out end...", group="Select a period 3 month", inline="16")

time_6m         = input.bool(defval=false, title="On/off 6 month", group="Select a period 6 month")
day_6m_in       = input.int(defval=01, title="Day in begin", group="Select a period 6 month", inline="17")
month_6m_in     = input.int(defval=12, title="Month in begin", group="Select a period 6 month", inline="17")
day_6m_in_      = input.int(defval=31, title="Day in end...", group="Select a period 6 month", inline="18")
month_6m_in_    = input.int(defval=12, title="Month in end...", group="Select a period 6 month", inline="18")
day_6m_out      = input.int(defval=01, title="Day out begin", group="Select a period 6 month", inline="19")
month_6m_out    = input.int(defval=06, title="Month out begin", group="Select a period 6 month", inline="19")
day_6m_out_     = input.int(defval=30, title="Day out end...", group="Select a period 6 month", inline="20")
month_6m_out_   = input.int(defval=06, title="Month out end...", group="Select a period 6 month", inline="20")

time_18m        = input.bool(defval=true, title="On/off 18 month", group="Select a period 18 month")
day_18m_in      = input.int(defval=01, title="Day in begin", group="Select a period 18 month", inline="21")
month_18m_in    = input.int(defval=03, title="Month in begin", group="Select a period 18 month", inline="21")
day_18m_in_     = input.int(defval=31, title="Day in end...", group="Select a period 18 month", inline="22")
month_18m_in_   = input.int(defval=03, title="Month in end...", group="Select a period 18 month", inline="22")
day_18m_out     = input.int(defval=01, title="Day out begin", group="Select a period 18 month", inline="23")
month_18m_out   = input.int(defval=11, title="Month out begin", group="Select a period 18 month", inline="23")
day_18m_out_    = input.int(defval=30, title="Day out end...", group="Select a period 18 month", inline="24")
month_18m_out_  = input.int(defval=11, title="Month out end...", group="Select a period 18 month", inline="24")


//======================================================================
//     Data preparation
//======================================================================

// FOR ALL
var years_array      = array.from(2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030)
var years_array_3m   = array.from(2012, 2013, 2015, 2016, 2017, 2019, 2020, 2021, 2023, 2024, 2025, 2027, 2028, 2029) // minus 2014, 2018, 2022, 2026, 2030
var years_array_6m1  = array.from(2010, 2014, 2018, 2022, 2026, 2030)
var years_array_6m2  = array.from(2011, 2015, 2019, 2023, 2027, 2031)
var years_array_18m1 = array.from(2012, 2016, 2020, 2024, 2028, 2032)
var years_array_18m2 = array.from(2013, 2017, 2021, 2025, 2029, 2033)

// FOR TABLE
var int[] date_1m_s_in_1  = array.new_int()
var int[] date_1m_s_in_2  = array.new_int()
var int[] date_1m_s_out_1 = array.new_int()
var int[] date_1m_s_out_2 = array.new_int()
var int[] date_1m_a_in_1  = array.new_int()
var int[] date_1m_a_in_2  = array.new_int()
var int[] date_1m_a_out_1 = array.new_int()
var int[] date_1m_a_out_2 = array.new_int()
var int[] date_1m_w_in_1  = array.new_int()
var int[] date_1m_w_in_2  = array.new_int()
var int[] date_1m_w_out_1 = array.new_int()
var int[] date_1m_w_out_2 = array.new_int()
var int[] date_3m_in_1    = array.new_int()
var int[] date_3m_in_2    = array.new_int()
var int[] date_3m_out_1   = array.new_int()
var int[] date_3m_out_2   = array.new_int()
var int[] date_6m_in_1    = array.new_int()
var int[] date_6m_in_2    = array.new_int()
var int[] date_6m_out_1   = array.new_int()
var int[] date_6m_out_2   = array.new_int()
var int[] date_18m_in_1   = array.new_int()
var int[] date_18m_in_2   = array.new_int()
var int[] date_18m_out_1  = array.new_int()
var int[] date_18m_out_2  = array.new_int()

// prepare years and months
var months      = array.new_int()
var year_array  = array.new_int()
var month_array = array.new_int()


if barstate.isfirst

    // prepare months for table
    for i = 0 to number_month - 1
        array.push(months, i)

    // prepare dates for table
    for elem in months
        array.push(year_array, year(timestamp(year(timenow), month(timenow) + elem, 1, 0, 0, 0)))
        array.push(month_array, month(timestamp(year(timenow), month(timenow) + elem, 1, 0, 0, 0)))

    // prepare dates for periods
    for elem in years_array
        array.push(date_1m_s_in_1, timestamp(year=elem, month=month_1m_s_in, day=day_1m_s_in))
        array.push(date_1m_s_in_2, timestamp(year=elem, month=month_1m_s_in_, day=day_1m_s_in_))
        array.push(date_1m_s_out_1, timestamp(year=elem, month=month_1m_s_out, day=day_1m_s_out))
        array.push(date_1m_s_out_2, timestamp(year=elem, month=month_1m_s_out_, day=day_1m_s_out_))

        array.push(date_1m_a_in_1, timestamp(year=elem, month=month_1m_a_in, day=day_1m_a_in))
        array.push(date_1m_a_in_2, timestamp(year=elem, month=month_1m_a_in_, day=day_1m_a_in_))
        array.push(date_1m_a_out_1, timestamp(year=elem, month=month_1m_a_out, day=day_1m_a_out))
        array.push(date_1m_a_out_2, timestamp(year=elem, month=month_1m_a_out_, day=day_1m_a_out_))

        array.push(date_1m_w_in_1, timestamp(year=elem, month=month_1m_w_in, day=day_1m_w_in))
        array.push(date_1m_w_in_2, timestamp(year=elem, month=month_1m_w_in_, day=day_1m_w_in_))
        array.push(date_1m_w_out_1, timestamp(year=elem, month=month_1m_w_out, day=day_1m_w_out))
        array.push(date_1m_w_out_2, timestamp(year=elem, month=month_1m_w_out_, day=day_1m_w_out_))

    for elem in years_array_3m
        array.push(date_3m_in_1, timestamp(year=elem, month=month_3m_in, day=day_3m_in))
        array.push(date_3m_in_2, timestamp(year=elem, month=month_3m_in_, day=day_3m_in_))
        array.push(date_3m_out_1, timestamp(year=elem, month=month_3m_out, day=day_3m_out))
        array.push(date_3m_out_2, timestamp(year=elem, month=month_3m_out_, day=day_3m_out_))

    for elem in years_array_6m1
        array.push(date_6m_in_1, timestamp(year=elem, month=month_6m_in, day=day_6m_in))
        array.push(date_6m_in_2, timestamp(year=elem, month=month_6m_in_, day=day_6m_in_))
    
    for elem in years_array_6m2
        array.push(date_6m_out_1, timestamp(year=elem, month=month_6m_out, day=day_6m_out))
        array.push(date_6m_out_2, timestamp(year=elem, month=month_6m_out_, day=day_6m_out_))

    for elem in years_array_18m1
        array.push(date_18m_in_1, timestamp(year=elem, month=month_18m_in, day=day_18m_in))
        array.push(date_18m_in_2, timestamp(year=elem, month=month_18m_in_, day=day_18m_in_))
    
    for elem in years_array_18m2
        array.push(date_18m_out_1, timestamp(year=elem, month=month_18m_out, day=day_18m_out))
        array.push(date_18m_out_2, timestamp(year=elem, month=month_18m_out_, day=day_18m_out_))


//======================================================================
//     Color theme
//======================================================================

var color_bg_tabel = color.new(color.gray, 90)
var color_bd_tabel = color.new(color.black, 40)
var color_tx_tabel = color.new(color.black, 20)

if mode
    color_bg_tabel := color.new(color.gray, 90)
    color_bd_tabel := color.new(color.white, 40)
    color_tx_tabel := color.new(color.white, 20)


//======================================================================
//     Backgrond color
//======================================================================

check_tf(startTimeArray, endTimeArray) =>
    // condition for bgcolor
    isInTimeFrame = false
    for i=0 to array.size(startTimeArray) - 1
        isInTimeFrame := time >= array.get(startTimeArray, i) and time <= array.get(endTimeArray, i)
        if isInTimeFrame
            break
    isInTimeFrame


// summer
bgcolor(time_1m_s == true ? check_tf(date_1m_s_in_1, date_1m_s_in_2) ? color.new(color.green, 85) : na : na)
bgcolor(time_1m_s == true ? check_tf(date_1m_s_out_1, date_1m_s_out_2) ? color.new(color.red, 85) : na : na)

// autumn
bgcolor(time_1m_a == true ? check_tf(date_1m_a_in_1, date_1m_a_in_2) ? color.new(color.green, 85) : na : na)
bgcolor(time_1m_a == true ? check_tf(date_1m_a_out_1, date_1m_a_out_2) ? color.new(color.red, 85) : na : na)

// winter
bgcolor(time_1m_w == true ? check_tf(date_1m_w_in_1, date_1m_w_in_2) ? color.new(color.green, 85) : na : na)
bgcolor(time_1m_w == true ? check_tf(date_1m_w_out_1, date_1m_w_out_2) ? color.new(color.red, 85) : na : na)

// 3 month
bgcolor(time_3m == true ? check_tf(date_3m_in_1, date_3m_in_2) ? color.new(color.green, 85) : na : na)
bgcolor(time_3m == true ? check_tf(date_3m_out_1, date_3m_out_2) ? color.new(color.red, 85) : na : na)

// 6 month
bgcolor(time_6m == true ? check_tf(date_6m_in_1, date_6m_in_2) ? color.new(color.green, 85) : na : na)
bgcolor(time_6m == true ? check_tf(date_6m_out_1, date_6m_out_2) ? color.new(color.red, 85) : na : na)

// 18 month
bgcolor(time_18m == true ? check_tf(date_18m_in_1, date_18m_in_2) ? color.new(color.green, 85) : na : na)
bgcolor(time_18m == true ? check_tf(date_18m_out_1, date_18m_out_2) ? color.new(color.red, 85) : na : na)


//======================================================================
//     Table
//======================================================================

var tbl = table.new(position.bottom_right, number_month + 1, 8, bgcolor = color_bg_tabel, border_color = color_bd_tabel, border_width = 1)

future_tf(_curent_year, _curent_month, startTimeArray, endTimeArray) =>
    // condition for bgcolor (table)
    isInTimeFrame = false
    _curent_day = timestamp(year = _curent_year, month = _curent_month, day = 1)
    
    for i = 0 to array.size(startTimeArray) - 1
        _start_day = timestamp(year = year(array.get(startTimeArray, i)), month = month(array.get(startTimeArray, i)), day = 1)
        _and_day   = timestamp(year = year(array.get(endTimeArray, i)), month = month(array.get(endTimeArray, i)), day = 1)
        isInTimeFrame := _curent_day >= _start_day and _curent_day <= _and_day
        
        if isInTimeFrame
            break
    isInTimeFrame


if table_on and barstate.islast

    // column 1
    table.cell(tbl, 0, 0, "Year", text_halign = text.align_left, text_color = color_tx_tabel)
    table.cell(tbl, 0, 1, "Month", text_halign = text.align_left, text_color = color_tx_tabel)
    table.cell(tbl, 0, 2, "1 month Summer", text_halign = text.align_left, text_color = color_tx_tabel)
    table.cell(tbl, 0, 3, "1 month Autumn", text_halign = text.align_left, text_color = color_tx_tabel)
    table.cell(tbl, 0, 4, "1 month Winter", text_halign = text.align_left, text_color = color_tx_tabel)
    table.cell(tbl, 0, 5, "3 month", text_halign = text.align_left, text_color = color_tx_tabel)
    table.cell(tbl, 0, 6, "6 month", text_halign = text.align_left, text_color = color_tx_tabel)
    table.cell(tbl, 0, 7, "18 month", text_halign = text.align_left, text_color = color_tx_tabel)


    // columns 2 - 12...
    for i=0 to number_month - 1
        _curent_year = array.get(year_array, i)
        _curent_month = array.get(month_array, i)

        // row 1 and row 2
        table.cell(tbl, 1 + i, 0, str.tostring(_curent_year), text_size=size.small, text_halign = text.align_center, text_color = color_tx_tabel)
        table.cell(tbl, 1 + i, 1, str.tostring(_curent_month), text_halign = text.align_center, text_color = color_tx_tabel)

        // row 3 - 8
        if future_tf(_curent_year, _curent_month, date_1m_s_in_1, date_1m_s_out_2)
            table.cell_set_bgcolor(tbl, 1 + i, 2, bgcolor = color.new(color.green, 25))
            if time_1m_s
                table.cell_set_text_color(tbl, 0, 2, text_color = color.blue)

        if future_tf(_curent_year, _curent_month, date_1m_a_in_1, date_1m_a_out_2)
            table.cell_set_bgcolor(tbl, 1 + i, 3, bgcolor = color.new(color.green, 25))
            if time_1m_a
                table.cell_set_text_color(tbl, 0, 3, text_color = color.blue)

        if future_tf(_curent_year, _curent_month, date_1m_w_in_1, date_1m_w_in_2) or future_tf(_curent_year, _curent_month, date_1m_w_out_1, date_1m_w_out_2)
            table.cell_set_bgcolor(tbl, 1 + i, 4, bgcolor = color.new(color.green, 25))
            if time_1m_w
                table.cell_set_text_color(tbl, 0, 4, text_color = color.blue)

        if future_tf(_curent_year, _curent_month, date_3m_in_1, date_3m_out_2)
            table.cell_set_bgcolor(tbl, 1 + i, 5, bgcolor = color.new(color.green, 25))
            if time_3m
                table.cell_set_text_color(tbl, 0, 5, text_color = color.blue)

        if future_tf(_curent_year, _curent_month, date_6m_in_1, date_6m_out_2)
            table.cell_set_bgcolor(tbl, 1 + i, 6, bgcolor = color.new(color.green, 25))
            if time_6m
                table.cell_set_text_color(tbl, 0, 6, text_color = color.blue)

        if future_tf(_curent_year, _curent_month, date_18m_in_1, date_18m_out_2)
            table.cell_set_bgcolor(tbl, 1 + i, 7, bgcolor = color.new(color.green, 25))
            if time_18m
                table.cell_set_text_color(tbl, 0, 7, text_color = color.blue)
