Harmonic Pattern Possibility Table
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RozaniGhani-RG

//@version=5
indicator('Harmonic Pattern Possibility Table', shorttitle = 'HPPT')

// 0. Inputs
// 1. Variables
// 2. Switches
// 3. Arrays
// 4. Custom functions
// 5. Construct

// ————————————————————————————————————————————————————————————————————————————— 0. Inputs {
T0       = 'Small font size recommended for mobile app or multiple layout'
value    = input.float( 0.371,                    'Value', minval  = 0.371, maxval = 0.913, step = 0.001,          tooltip = '0.371 <= Value <= 0.913')
i_s_ABC  = input.string('All',    'ALT BAT /  BAT / CRAB', options = ['All', 'ALT BAT', 'BAT', 'CRAB'],            tooltip = 'Value = 0.382')           // 'ALT BAT, BAT, CRAB'
i_s_BC   = input.string('All',               'BAT / CRAB', options = ['All',            'BAT', 'CRAB'],            tooltip = '0.383 <= Value <= 0.500') // 'ALT BAT, BAT, CRAB'
i_s_CG   = input.string('All',           'CRAB / GARTLEY', options = ['All',                   'CRAB', 'GARTLEY'], tooltip = '0.599 <= Value <= 0.618') // 'CRAB', 'GARTLEY'
i_s_font = input.string('normal',             'Font size', options = ['tiny', 'small',  'normal', 'large', 'huge'], tooltip = T0)
i_s_Y    = input.string('middle',        'Table Position', options = ['top',  'middle', 'bottom'], inline = '0')
i_s_X    = input.string('center',                      '', options = ['left', 'center', 'right'],  inline = '0')
// }
// ————————————————————————————————————————————————————————————————————————————— 1. Variables {
var string animal = na
var animalTable   = table.new(i_s_Y + '_' + i_s_X,  12, 14, border_width = 1)
cn      = color.new(color.blue, 100)
cw      = color.white
cy      = color.yellow
str_ABC = 'ALT BAT, BAT, CRAB'
str_BC  = 'BAT, CRAB'
str_CG  = 'CRAB, GARTLEY'
p0      = math.rphi
p1      = math.phi
p2      = math.rphi + 2
p3      = math.rphi + 3
// }
// ————————————————————————————————————————————————————————————————————————————— 2. Switches {
[d_min_ABC, d_max_ABC, d_nom_ABC, s_nom_ABC] = switch i_s_ABC
    //           [d_min_ABC, d_max_ABC, d_nom_ABC, s_nom_ABC]
    'All'     => [        2,        p3,     1.13 ,      1.27]
    'ALT BAT' => [        2,        p3,     1.13 ,      1.27]
    'BAT'     => [       p1,        p2,      .886,      1.13]
    'CRAB'    => [       p2,        p3,        p1,      2.  ]

[d_min_BC, d_max_BC, d_nom_BC, s_nom_BC] = switch i_s_BC
    //        [d_min_BC, d_max_BC, d_nom_BC, s_nom_BC]
    'All'  => [      p1,       p2,       p2,       p2]
    'BAT'  => [      p1,       p2,     .886,    1.13 ]
    'CRAB' => [      p2,       p3,       p1,    2.   ]

[d_min_CG, d_max_CG, d_nom_CG, s_nom_CG] = switch i_s_CG
    //           [d_min_CG, d_max_CG, d_nom_CG, s_nom_CG]
    'All'     => [      p2,       p3,       p1,    2.   ]
    'CRAB'    => [      p2,       p3,       p1,    2.   ]
    'GARTLEY' => [      p1,       p1,     .786,    1.   ]
// }
// ————————————————————————————————————————————————————————————————————————————— 3. Arrays {
//                                   0          1         2       3         4          5            6            7
possible_animal = array.from('ALT BAT',   str_ABC,   str_BC, 'CRAB',   str_CG, 'GARTLEY', 'BUTTERFLY', 'DEEP CRAB')
selected_animal = array.from('ALT BAT',   i_s_ABC,   i_s_BC, 'CRAB',   i_s_CG, 'GARTLEY', 'BUTTERFLY', 'DEEP CRAB')
priority_animal = array.from('ALT BAT', 'ALT BAT',    'BAT', 'CRAB',   'CRAB', 'GARTLEY', 'BUTTERFLY', 'DEEP CRAB')
b_min           = array.from(     .371,      .382,     .383,   .501,     .599,      .619,        .762,        .886)
b_max           = array.from(     .381,      .382,     .5  ,   .598,       p0,      .637,        .81 ,        .93 )
c_min           = array.from(     .382,      .382,     .382,   .382,     .382,      .382,        .382,        .382)
c_max           = array.from(     .886,      .886,     .886,   .886,     .886,      .886,        .886,        .886)
d_min           = array.from(    2.   , d_min_ABC, d_min_BC,     p2, d_min_CG,     1.13 ,          p1,          p2)
d_max           = array.from(       p3, d_max_ABC, d_max_BC,     p3, d_max_CG,     1.618,       2.24 ,          p3)
d_nom           = array.from(    1.13 , d_nom_ABC, d_nom_BC,     p1, d_nom_CG,      .786,       1.27 ,          p1)
s_nom           = array.from(    1.27 , s_nom_ABC, s_nom_BC,  2.   , s_nom_CG,     1.   ,       1.414,        2.  )
min_max         = array.from('Min', 'Max')
pattern         = array.from('Possible', 'Priority', 'Selected')
arr_bool = array.new_bool(8)
for _index = 0 to 7
    array.set(arr_bool, _index, value >= array.get(b_min, _index) and value <= array.get(b_max, _index)) 
// }
// ————————————————————————————————————————————————————————————————————————————— 4. Custom functions {
color_get(_id, int _index) => array.get(_id, _index) <= 1 ? color.red : color.blue
str_get(_id, int _index, int _int = 0) =>
    expr = switch _int
        1 => '>= '
        2 => '<= '
    txt = str.tostring( array.get(_id, _index), expr + '0.000')
    txt
// }
// ————————————————————————————————————————————————————————————————————————————— 5. Construct {
if array.includes(arr_bool, true)
    animal := array.get(possible_animal, array.indexof(arr_bool, array.includes(arr_bool, true)))

if barstate.islast
    // title from input
    table.cell(animalTable,  0, 0, 'Harmonic Pattern Possibility Table', bgcolor = cw, text_size = i_s_font), table.merge_cells(animalTable, 0, 0, 11, 0)
    table.cell(animalTable,  0, 1,                     'Input (B = XA)', bgcolor = cw, text_size = i_s_font), table.merge_cells(animalTable, 0, 1,  5, 1)
    table.cell(animalTable,  6, 1,                    'Output (D = XA)', bgcolor = cw, text_size = i_s_font), table.merge_cells(animalTable, 6, 1, 11, 1)
    table.cell(animalTable,  0, 2,         str.tostring(value, '0.000'), bgcolor = cy, text_size = i_s_font), table.merge_cells(animalTable, 0, 2,  5, 2)
    table.cell(animalTable,  6, 2,                               animal, bgcolor = cy, text_size = i_s_font), table.merge_cells(animalTable, 6, 2, 11, 2)

    // blank row
    table.cell(animalTable,  0, 3,                                  ' ', bgcolor = cn, text_size = i_s_font, text_color = cn), table.merge_cells(animalTable, 0, 3, 11, 3)

    // sub title no 1
    table.cell(animalTable,  0, 4,                             'B = XA', bgcolor = cw, text_size = i_s_font), table.merge_cells(animalTable, 0, 4,  5, 4)
    table.cell(animalTable,  6, 4,                             'C = AB', bgcolor = cw, text_size = i_s_font), table.merge_cells(animalTable, 6, 4,  7, 4)
    table.cell(animalTable,  8, 4,                             'D = BC', bgcolor = cw, text_size = i_s_font), table.merge_cells(animalTable, 8, 4,  9, 4)
    table.cell(animalTable, 10, 4,                             'D = XA', bgcolor = cw, text_size = i_s_font)
    table.cell(animalTable, 11, 4,                          'Stop Loss', bgcolor = cw, text_size = i_s_font)

    // sub title no 2
    table.cell(animalTable, 0, 5,                                  'No', bgcolor = cw)
    for _column = 0 to 2
        table.cell(animalTable, _column + 3, 5,  array.get(pattern, _column) + '\nPattern', bgcolor = cw, text_size = i_s_font)    

    // sub title no 2 (Min, Max)
    for _column = 0 to 1
        table.cell(animalTable, _column +  1, 5, array.get(min_max, _column), bgcolor = cw, text_size = i_s_font)
        table.cell(animalTable, _column +  6, 5, array.get(min_max, _column), bgcolor = cw, text_size = i_s_font) 
        table.cell(animalTable, _column +  8, 5, array.get(min_max, _column), bgcolor = cw, text_size = i_s_font)   
        table.cell(animalTable, _column + 10, 5,                       'Nom', bgcolor = cw, text_size = i_s_font)

    // values for each animal pattern
    for _row = 0 to 7
        table.cell(animalTable,  0, _row + 6,               str.tostring(_row),    text_size = i_s_font, bgcolor = cw)
        table.cell(animalTable,  1, _row + 6,   str_get(          b_min, _row, 1), text_size = i_s_font, bgcolor = color_get(b_min, _row))
        table.cell(animalTable,  2, _row + 6,   str_get(          b_max, _row, 2), text_size = i_s_font, bgcolor = color_get(b_max, _row))
        table.cell(animalTable,  3, _row + 6, array.get(possible_animal, _row),    text_size = i_s_font, bgcolor = cw)
        table.cell(animalTable,  4, _row + 6, array.get(priority_animal, _row),    text_size = i_s_font, bgcolor = cw)
        table.cell(animalTable,  5, _row + 6, array.get(selected_animal, _row),    text_size = i_s_font, bgcolor = cw)
        table.cell(animalTable,  6, _row + 6,   str_get(          c_min, _row, 1), text_size = i_s_font, bgcolor = color_get(c_min, _row))
        table.cell(animalTable,  7, _row + 6,   str_get(          c_max, _row, 2), text_size = i_s_font, bgcolor = color_get(c_max, _row))
        table.cell(animalTable,  8, _row + 6,   str_get(          d_min, _row, 1), text_size = i_s_font, bgcolor = color_get(d_min, _row))
        table.cell(animalTable,  9, _row + 6,   str_get(          d_max, _row, 2), text_size = i_s_font, bgcolor = color_get(d_max, _row))
        table.cell(animalTable, 10, _row + 6,   str_get(          d_nom, _row),    text_size = i_s_font, bgcolor = color_get(d_nom, _row))
        table.cell(animalTable, 11, _row + 6,   str_get(          s_nom, _row),    text_size = i_s_font, bgcolor = color_get(s_nom, _row))

    // if animal is true
    if array.includes(possible_animal, animal)
        for _column = 0 to 11
            table.cell_set_bgcolor(animalTable, _column, array.indexof(arr_bool, array.includes(arr_bool, true)) + 6, cy)
// }