Harmonic Table Combo Point B
// 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 Table Combo Point B', overlay = true)

// 0. Inputs
// 1. Variables, Switches and Arrays
// 2. Custom functions
// 3. Construct

// ————————————————————————————————————————————————————————————————————————————— 0. Inputs {
T0        = 'Small font size recommended for mobile app or multiple layout'
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')
i_f_value = input.float( 0.371,                    'Value', minval  = 0.371, maxval = 0.930, step = 0.001,           tooltip = '0.371 <= Value <= 0.930')
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') // 'BAT, CRAB'
i_s_CG    = input.string('All',           'CRAB / GARTLEY', options = ['All',                   'CRAB', 'GARTLEY'],  tooltip = '0.599 <= Value <= 0.618') // 'CRAB', 'GARTLEY'
G2        = 'SPECIAL SITUATION (D = XA)'
T2        = 'Change value D = XA\n if'
i_f_gart  = input.float(0.786,                   'Gartley', options =[0.786, 0.886], group = G2, tooltip = T2 + 'Gartley was found.\nDefault : 0.786\nSpecial : 0.886')
i_f_crab  = input.float(1.618,          'Crab / Deep Crab', options =[1.618, 1.902], group = G2, tooltip = T2 + 'Crab / Deep Crab was found.\nDefault : 1.618\nSpecial : 1.902')
// }
// ————————————————————————————————————————————————————————————————————————————— 1. Variables, Switches and Arrays {
p0      = math.rphi
p1      = math.phi
p2      = math.rphi + 2
p3      = math.rphi + 3
[bc1_gart, bc2_gart, sl_gart] = switch i_f_gart
// Output =>  bc1_gart, bc2_gart, sl_gart
    0.786 => [   1.130,       p1,   1.   ]
    0.886 => [      p1,       p2,   1.13 ]
var TBL = table.new(i_s_Y + '_' + i_s_X, columns = 10, rows = 9, border_width = 1)
title   = array.from('INPUT\n(B=XA)', 'POSSIBLE', 'PRIORITY', 'COMPARISON', 'B = XA', 'C = AB', 'D = BC', 'D = XA', 'STOP\nLOSS')
str_ABC = 'ALT BAT, BAT, CRAB'
str_BC  = 'BAT, CRAB'
str_CG  = 'CRAB, GARTLEY'
//                                   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')
priority_animal = array.from('ALT BAT', 'ALT BAT',    'BAT', 'CRAB',   'CRAB', 'GARTLEY', 'BUTTERFLY', 'DEEP CRAB')
selected_animal = array.from('ALT BAT',   i_s_ABC,   i_s_BC, 'CRAB',   i_s_CG, '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 )
arr_bool        = array.new_bool(8)
for _index = 0 to 7
    array.set(arr_bool, _index, i_f_value >= array.get(b_min, _index) and i_f_value <= array.get(b_max, _index)) 
//                                   0,     1,        2,         3,           4,           5
animal_name     = array.from('ALT BAT', 'BAT',   'CRAB', 'GARTLEY', 'BUTTERFLY', 'DEEP CRAB')    
arr_B_XA1       = array.from(     .371,  .382,     .382,      .599,        .599,        .886) // B = XA ==|=> Trade Identification
arr_B_XA2       = array.from(     .382,  .500,     .618,      .637,        .637,        .913) //          |
arr_C_AB1       = array.from(     .382,  .382,     .382,      .382,        .382,        .382) // C = AB   |
arr_C_AB2       = array.from(     .886,  .886,     .886,      .886,        .886,        .886) //        ==|
arr_D_BC1       = array.from(    2.   ,    p1,       p2,  bc1_gart,       1.618,       2.   ) // D = BC ==|=> Trade Execution - PRZ (Potential Reversal Zone)
arr_D_BC2       = array.from(       p3,    p2,       p3,  bc2_gart,       2.24 ,       3.618) //          |
arr_D_XA        = array.from(    1.13 ,  .886, i_f_crab,  i_f_gart,       1.27 ,    i_f_crab) // D = XA ==|
arr_E_SL        = array.from(    1.27 , 1.13 ,    2.   ,   sl_gart,       1.414,       2.   ) // Stop Loss => Trade Management (Page 174)
// }
// ————————————————————————————————————————————————————————————————————————————— 2. Custom functions {
f_str(_id, string _value)                                      => str.tostring(array.get(_id, array.indexof(animal_name, _value)), '0.000')
f_cell(int _column, int _row, string _text, bool _bool = true) =>
    table.cell(TBL, _column, _row, _text, bgcolor = color.white, text_halign = _bool ? text.align_left : text.align_center, text_size = i_s_font)
f_set(int _column, int _row, string _text)                     => table.cell_set_text(TBL, _column, _row, _text)
// }
// ————————————————————————————————————————————————————————————————————————————— 3. Construct {
if barstate.islast
    // row titles
    for _row = 0 to 8
        f_cell(0, _row, array.get(title, _row), false)
    // row variables
    new    = array.get(possible_animal, array.indexof(arr_bool, array.includes(arr_bool, true)))
    prior  = array.get(priority_animal, array.indexof(arr_bool, array.includes(arr_bool, true)))
    select = array.get(selected_animal, array.indexof(arr_bool, array.includes(arr_bool, true)))
    split  = str.split(new, ', ')
    for _column = 0 to array.size(split) - 1
        f_cell(_column + 1, 0, str.tostring(i_f_value, '0.000'), false)
        f_cell(_column + 1, 1,                             new)
        f_cell(_column + 1, 2,                           prior)
        f_cell(_column + 1, 3,                          select)
    // row ratios
    for _index = 0 to array.size(split) - 1
        f_cell(_index + 1, 3,            array.get(split, _index) + '\n' + f_str( arr_D_XA, array.get(split, _index)) + ' XA') // Pattern index
        f_cell(_index + 1, 4, f_str(arr_B_XA1, array.get(split, _index)) + ';\n' + f_str(arr_B_XA2, array.get(split, _index))) // B = XA
        f_cell(_index + 1, 5, f_str(arr_C_AB1, array.get(split, _index)) + ';\n' + f_str(arr_C_AB2, array.get(split, _index))) // C = AB
        f_cell(_index + 1, 6, f_str(arr_D_BC1, array.get(split, _index)) + ';\n' + f_str(arr_D_BC2, array.get(split, _index))) // D = BC
        f_cell(_index + 1, 7,                                                      f_str( arr_D_XA, array.get(split, _index))) // D = XA
        f_cell(_index + 1, 8,                                                      f_str( arr_E_SL, array.get(split, _index))) // E = SL
    // Specific combo for ALT BAT /  BAT / CRAB
    if array.size(split) == 3
        if i_s_ABC != 'All'
            f_set( 0, 3, 'SELECTED')
        if i_s_ABC == 'ALT BAT'
            table.clear(TBL, 2, 0, 3, 8)
        else if i_s_ABC == 'BAT'
            table.clear(TBL, 1, 0, 1, 8)
            table.clear(TBL, 3, 0, 3, 8)
        else if i_s_ABC == 'CRAB'
            table.clear(TBL, 1, 0, 2, 8)
        else
            for _row = 0 to array.size(split) - 1
                table.merge_cells(TBL, 1, _row, array.size(split), _row)
    // Combo for
    // BAT / CRAB
    // CRAB / GARTLEY
    if array.size(split) == 2
        pos1 = array.get(split, 1)
        if i_s_BC != 'All' or i_s_CG != 'All'        
            f_set( 0, 3, 'SELECTED')
        if i_s_BC == 'BAT' or i_s_CG == 'CRAB'
            table.clear(TBL, 2, 0, 2, 8)
        else if i_s_BC == 'CRAB'or i_s_CG == 'GARTLEY'
            table.clear(TBL, 1, 0, 1, 8)
        else
            for _row = 0 to array.size(split) - 1
                table.merge_cells(TBL, 1, _row, array.size(split), _row)
    // CRAB / GARTLEY / BUTTERFLY / DEEP CRAB
    if array.size(split) == 1
        table.clear(TBL, 0, 1, 1, 2)
        f_cell(0, 3, 'POSSIBLE', false)
// }