Simple OHLC Custom Range Interactive
// 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('Simple OHLC Custom Range Interactive', 'SO_CRI',true)
// 0. Imports
// 1. Inputs
// 2. Variables / Array Initializations
// 3. Custom Functions
// 4. Variables / Array Setups
// 5. Constructs
// ————————————————————————————————————————————————————————————————————————————— 0. Imports {
import RozaniGhani-RG/PriceTimeInteractive/2 as pti
import RozaniGhani-RG/DeleteArrayObject/1    as obj
import RozaniGhani-RG/HarmonicSwitches/1     as sw
// }
// ————————————————————————————————————————————————————————————————————————————— 1. Inputs {
int i_ts  = timestamp(   '2022-12')
int i_t   = input.time(      i_ts,              'Point', confirm = true)
i_s_price = input.string('Simple',         'Price Name', options = ['Simple', 'Full'])
i_extend  = input.string(   'None',      'Extend lines', options = [ 'Right', 'Left', 'Both', 'None'])
G1        = 'HELPER'
T1        = '1) Tick to show table\n2) Small font size recommended for mobile app or multiple layout'
T2        = 'Table must be tick before change table position'
i_b_price = input.bool(     false, 'Show Price on axis', group = G1)
i_b_table = input.bool(      true,       'Show Table |', group = G1, inline = 'Table1')
i_s_font  = input.string('normal',          'Font size', group = G1, inline = 'Table1', options = ['tiny',  'small', 'normal', 'large', 'huge'], tooltip = T1)
i_s_Y     = input.string('bottom',     'Table Position', group = G1, inline = 'Table2', options = [ 'top', 'middle', 'bottom'])
i_s_X     = input.string(  'left',                   '', group = G1, inline = 'Table2', options = ['left', 'center', 'right'],                   tooltip = T2)
// }
// ————————————————————————————————————————————————————————————————————————————— 2. Variables / Array Initializations {
[O, H, L, C]         = pti.ohlc_time(i_t)
float_OHLC           = array.from(O, H, L, C)
var line_OHLC        = array.new_line(4),  obj.delete(line_OHLC)
var fill_OHLC        = array.new_linefill(4),  obj.delete(fill_OHLC)
bool_price           = array.new_bool(3)
col_price            = array.from(color.teal, color.red, color.blue)
var color col        = na
var string str       = na
var label label_OHLC = na, label.delete(label_OHLC)
var linefill fill    = na, linefill.delete(fill)
var TBL              = table.new(i_s_Y + '_' + i_s_X, 5, 4, border_width = 1)
[str_O, str_H, str_L, str_C] = switch i_s_price
    //          [ str_O,  str_H, str_L,   str_C]
    'Simple' => [   'O',    'H',   'L',     'C']
    'Full'   => ['OPEN', 'HIGH', 'LOW', 'CLOSE']
extend = switch i_extend
    'Right' => extend.right
    'Left'  => extend.left
    'Both'  => extend.both
    'None'  => extend.none
// }
// ————————————————————————————————————————————————————————————————————————————— 3. Custom Functions {
f_resInMinutes() => 
    _resInMinutes = timeframe.multiplier * (
      timeframe.isseconds ? 1. / 60             :
      timeframe.isminutes ? 1.                  :
      timeframe.isdaily   ? 60. * 24            :
      timeframe.isweekly  ? 60. * 24 * 7        :
      timeframe.ismonthly ? 60. * 24 * 30.4375  : na)
f_row(int _row, string _str, float _float, color _col) =>
    table.cell(TBL, 3, _row,                          _str, text_size = i_s_font, bgcolor = _col)
    table.cell(TBL, 4, _row, str.tostring(_float, '#.000'), text_size = i_s_font, bgcolor = _col)
// }
// ————————————————————————————————————————————————————————————————————————————— 4. Variables / Array Setups {
array.set(bool_price, 0 , C > O)
array.set(bool_price, 1 , C < O)
array.set(bool_price, 2 , C == O)
if array.includes(bool_price, true)
    col   := array.get(  col_price, array.indexof(bool_price, array.includes(bool_price, true)))
array.set(line_OHLC, 0, line.new(i_t, array.get(float_OHLC, 0), int(i_t + f_resInMinutes() * 60 * 1000 * 14), array.get(float_OHLC, 0), xloc.bar_time, extend, col, line.style_dotted))
array.set(line_OHLC, 1, line.new(i_t, array.get(float_OHLC, 1), int(i_t + f_resInMinutes() * 60 * 1000 * 14), array.get(float_OHLC, 1), xloc.bar_time, extend, color.new(col, 100), line.style_dotted))
array.set(line_OHLC, 2, line.new(i_t, array.get(float_OHLC, 2), int(i_t + f_resInMinutes() * 60 * 1000 * 14), array.get(float_OHLC, 2), xloc.bar_time, extend, color.new(col, 100), line.style_dotted))
array.set(line_OHLC, 3, line.new(i_t, array.get(float_OHLC, 3), int(i_t + f_resInMinutes() * 60 * 1000 * 14), array.get(float_OHLC, 3), xloc.bar_time, extend, col, line.style_dotted))
str        := 'O : ' + str.tostring(O, '#.000') + '\nH : ' + str.tostring(H, '#.000') + '\nL : ' + str.tostring(L, '#.000') + '\nC : ' + str.tostring(C, '#.000')
fill       := linefill.new(array.get(line_OHLC, 1), array.get(line_OHLC, 2), color.new(col, 80))
label_OHLC := label.new(i_t, L - (ta.atr(30) * 0.6), '', xloc = xloc.bar_time, color = col, style = label.style_label_up, tooltip = str)
// }
// ————————————————————————————————————————————————————————————————————————————— 5. Constructs {
if barstate.islast and i_b_table
    // Candle Construct
    table.cell(       TBL, 0, 0, '|', text_size = i_s_font, bgcolor = color.new(color.blue, 100), text_color = col)
    table.cell(       TBL, 0, 1, '|', text_size = i_s_font, bgcolor = color.new(color.blue, 100), text_color = color.new(color.blue, 100))
    table.cell(       TBL, 0, 3, '|', text_size = i_s_font, bgcolor = color.new(color.blue, 100), text_color = col)
    table.cell(       TBL, 1, 1, ' ', text_size = i_s_font, bgcolor = col)
    table.cell(       TBL, 2, 1, '|', text_size = i_s_font, bgcolor = color.new(color.blue, 100), text_color = color.new(color.blue, 100))
    table.merge_cells(TBL, 0, 0, 2, 0)
    table.merge_cells(TBL, 0, 1, 0, 2)
    table.merge_cells(TBL, 0, 3, 2, 3)
    table.merge_cells(TBL, 1, 1, 1, 2)
    table.merge_cells(TBL, 2, 1, 2, 2)
    // Candle values
    f_row(0, str_H, H, col)
    f_row(3, str_L, L, col)
    if C > O
        f_row(1, str_C, C, col)
        f_row(2, str_O, O, col)
    else
        f_row(1, str_O, O, col)
        f_row(2, str_C, C, col)
// Show Price on axis
plot(time == i_t and i_b_price ? O : na, 'O', col)
plot(time == i_t and i_b_price ? H : na, 'H', col)
plot(time == i_t and i_b_price ? L : na, 'L', col)
plot(time == i_t and i_b_price ? C : na, 'C', col)
// }