ASG Delta %
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Asgardian_

//@version=5

indicator(title="ASG Delta %", overlay=true)

i_normal		= input.bool(title="Norm ", defval=true, inline='row1')
i_reverse		= input.bool(title="Rev ", defval=true, inline='row1')
i_extra			= input.bool(title="Ext", defval=true, inline='row1')
i_arrow			= input.bool(title="↑↓", defval=false, inline='row1')
i_percent		= input.bool(title="%", defval=false, inline='row1')
i_size 			= input.string(title='', defval='[BOX]', options=["[BOX]", 'Tiny', 'Small', 'Normal', 'Large', 'Huge'], inline = 'row1')

i_startDate		= input.time(title='From Date/Time', defval=timestamp("1 MAY 2023"), confirm=true)
i_endDate		= input.time(title='To Date/Time', defval=timestamp("14 JUN 2023"), confirm=true)

i_col_bull		= input.color(title='Bull', defval=color.new(color.green, 70), inline='row3')
i_col_bear		= input.color(title='Bear', defval=color.new(color.red, 70), inline='row3')
i_col_normal	= input.color(title='Norm', defval=color.new(color.white, 85), inline='row3')
i_col_border	= input.color(title='Bord', defval=color.new(color.white, 50), inline='row3')
i_col_text		= input.color(title='Text', defval=color.new(color.white, 25), inline='row3')

size = i_size == 'Tiny' ? size.tiny : i_size == 'Small' ? size.small : i_size == 'Normal' ? size.normal : i_size == 'Large' ? size.large : i_size == 'Huge' ? size.huge : size.normal
dt = time - time[1]

f_draw_box(_x1, _y1, _x2, _y2, _dir, _text, _just, _col) =>	
	box = box.new(_x1, _y1, _x2, _y2, xloc=xloc.bar_time, border_color=i_col_border, border_width=1, bgcolor=_col, text=_text, text_color=i_col_text, text_halign=_just, text_font_family=font.family_monospace, text_size=size.auto)
	box.delete(box[1])

f_draw_extra_lines(_x, _y, _min, _max) =>
	topLine=line.new(x1=_x + (dt*2), y1=_max, x2=_x + (dt*7), y2=_max, xloc=xloc.bar_time, color=i_col_text,  style=line.style_solid, width=1)
	line.delete(topLine[1])

	currentLine=line.new(x1=_x + (dt*2), y1=_y, x2=_x + (dt*7), y2=_y, xloc=xloc.bar_time, color=i_col_text,  style=line.style_solid, width=1)
	line.delete(currentLine[1])

	bottomLine=line.new(x1=_x + (dt*2), y1=_min, x2=_x + (dt*7), y2=_min, xloc=xloc.bar_time, color=i_col_text,  style=line.style_solid, width=1)
	line.delete(bottomLine[1])

f_draw_extra_label(_x, _y, _text, _just) =>
	lbl=label.new(x=_x, y=_y, text=_text, xloc=xloc.bar_time, color=color.new(#ffffff, 100), style=label.style_label_left ,textcolor=i_col_text, textalign=_just, text_font_family=font.family_monospace, size=size)
	label.delete(lbl[1])

f_get_percentage(_from, _to) =>
	math.round(((_from - _to) / _to)*100, 2)

f_get_display_text(_direction, _fromY, _toY)=>
	string displayN='', string displayR=''
	
	if i_normal
		displayN := str.format("{0,number,###.00}", f_get_percentage(_fromY, _toY))+(i_percent?'%':na)
	
	if i_reverse
		displayR := str.format("{0,number,###.00}", f_get_percentage(_toY, _fromY))+(i_percent?'%':na)
	
	if (i_normal and i_reverse)
		if str.substring(displayN, 0, 1) =='-'
			displayR := ' ' + displayR
		if str.substring(displayR, 0, 1) == '-'
			displayN := ' ' + displayN

	if i_arrow and i_normal
		displayN := (_direction ? '▲' : '▼'	)+displayN
	if i_arrow and i_reverse
		displayR := (_direction ? '▼' : '▲')+displayR
		
	_direction ? displayN + (i_normal and i_reverse?'\n':na) + displayR : displayR + (i_normal and i_reverse?'\n':na) + displayN

var HHTime = 0, var LLTime = 0
var float HH = 10e-10, var float LL = 10e10

if i_startDate <= time and i_endDate >= time
	if high > HH
		HH := high
		HHTime := time
	if low < LL
		LL := low
		LLTime := time
 
if barstate.islast
	bool direction = false,	float fromY = 0.0,	float toY = 0.0

	if LLTime < HHTime
		direction := true // uptrend
		fromY := HH
		toY := LL
	else
		direction := false // downtrend
		fromY := LL
		toY := HH

	// main delta
	f_draw_box(i_startDate, fromY, i_endDate, toY, direction, f_get_display_text(direction, fromY, toY), text.align_center, direction ? i_col_bull : i_col_bear)

	// extra deltas
	minVal = math.min(close, math.min(fromY, toY))
	maxVal = math.max(close, math.max(fromY, toY))

	if i_extra and minVal < close and close < maxVal
		if i_size == '[BOX]'
			width = i_endDate + ((i_endDate - i_startDate)/2)
			f_draw_box(i_endDate+(dt*0), maxVal, width, close, direction, f_get_display_text(direction, direction?maxVal:close, direction?close:maxVal), text.align_center, i_col_normal)
			f_draw_box(i_endDate+(dt*0), minVal, width, close, direction, f_get_display_text(direction, direction?close:minVal, direction?minVal:close), text.align_center, i_col_normal)
		else
			f_draw_extra_lines(i_endDate, close, minVal, maxVal)
			f_draw_extra_label(i_endDate, (close + maxVal) / 2, f_get_display_text(direction, direction?maxVal:close, direction?close:maxVal), text.align_left)
			f_draw_extra_label(i_endDate, (close + minVal) / 2, f_get_display_text(direction, direction?close:minVal, direction?minVal:close), text.align_left)
		