Calculate target by Range [Wyckoff,PnF]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © meomeo105

//@version=5
indicator(title = 'Calculate target by Range [Wyckoff,PnF]',shorttitle = "Target",overlay = true)

DefaultSetting = "DefaultSetting"
mode = input.string(title='Box Size Assingment Method', defval='ATR', options=['ATR','Traditional'],group = DefaultSetting)
_modevalue = input.float(title='Value ATR/Traditional', defval=14, minval=0.000000000000001,group = DefaultSetting)
modevalue = mode=='ATR' ? math.ceil(_modevalue) : _modevalue
reversal = input.int(1, title='Reversal', minval=1,group = DefaultSetting)
_source = input.string(defval='Close', title='Source', options=['Close', 'High/Low'],group = DefaultSetting)
source = _source == "High/Low" ? "hl" : "close"
time1 = input.time(defval=0, title='Time Start',confirm = true,group = DefaultSetting , inline = "time1")
time2 = input.time(defval=0, title='End of Range',confirm = true , inline = "time2",group = DefaultSetting)

// Input Table
group_table = 'Table Infomation'
string tableYpos = input.string('top', '↕', inline='01', group=group_table, options=['top', 'middle', 'bottom'])
string tableXpos = input.string('right', '↔', inline='01', group=group_table, options=['left', 'center', 'right'], tooltip='Position on the chart.')
string textSize_ = input.string('Auto', 'Table Text Size', options=['Auto', 'Tiny', 'Small', 'Normal', 'Large', 'Huge'], group=group_table)
string textSize = textSize_ == 'Auto' ? size.auto : textSize_ == 'Tiny' ? size.tiny : textSize_ == 'Small' ? size.small : textSize_ == 'Normal' ? size.normal : textSize_ == 'Large' ? size.large : size.huge
color cell_col = input.color(color.white, 'Color', group=group_table)

bgcolor(time == time1 or time == time2 ? color.blue : na)
pnfTicker = ticker.pointfigure(syminfo.tickerid, source, mode, modevalue, reversal)
_time = request.security(pnfTicker, timeframe.period, time, barmerge.gaps_on)
_box = request.security(pnfTicker, timeframe.period, close > open ? open - close[1] : close[1] - open, barmerge.gaps_on)

_box := na(_box) ? _box[1] : math.abs(_box)
box = mode == 'ATR' ? _box : modevalue
pnfcolumns = _time >= math.min(time1,time2) and _time <= math.max(time1,time2) ? 1 : 0
//----------Show infomation-----------
// Table (collumn,row)
var table tableInfo = table.new(tableYpos + '_' + tableXpos, 1, 1, border_width=1)
table.cell(tableInfo, 0, 0, str.tostring(ta.cum(pnfcolumns)) + " * " + str.tostring(box) + " * " + str.tostring(reversal) + " = "  + str.tostring(ta.cum(pnfcolumns)*box*reversal) , text_color=cell_col, bgcolor=color.new(cell_col, 90), text_size=textSize)
