MTF High and Low Fractions
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © geneclash
//
// Acknowledgement:
//
// @HeWhoMustNotBeNamed - Previous High/Low MTF
// https://www.tradingview.com/script/DNqSoMlx-Previous-High-Low-MTF/
//
//@version=5
indicator('MTF high and low fractions', overlay=true, max_lines_count=500, max_labels_count=500)
tf1 = input.timeframe(defval='D', title='Timeframe for High/Low')
type = input.string("1/4",title="Levels:",options=["1/3","1/4","1/8"])
lineCount = input.int(30,title="Total Level Count",step=2,minval=2)/2

showhist = input(defval=false, title='Show Historical Lines', group='Lines & Labels')
showlabel = input(defval=false, title='Show Price Labels', group='Lines & Labels')
offsetlabel = input.int(3,title="Label Offset", group='Lines & Labels')
linestyle2 = input.string(defval='Solid', title="Line Style",options=['Solid', 'Dotted', 'Dashed'], group='Lines & Labels')
linestyle1 = linestyle2 == 'Solid' ? line.style_solid : linestyle2 == 'Dotted' ? line.style_dotted : line.style_dashed
lwidth = input.int(defval=1, minval=1, maxval=4, title='Line Width', group='Lines & Labels')
color1 = input.color(defval=color.white, title='Color (Lines & Labels)', group='Lines & Labels')

hhigh = request.security(syminfo.ticker, tf1, high[1], lookahead=barmerge.lookahead_on)
hlow = request.security(syminfo.ticker, tf1, low[1], lookahead=barmerge.lookahead_on)
hbar = request.security(syminfo.ticker, tf1, barstate.islast)

var division = 1
if type == "1/3"
    division := 3
else if type == "1/4"
    division := 4
else if type == "1/8"
    division := 8

range1 = (hhigh - hlow) / division
zerolevel = hlow

var line highline = na
var line lowline = na

var lines = array.new_line()
var labels = array.new_label()

x1Value = bar_index + offsetlabel

var label highlabel = label.new(x1Value, hhigh, style=label.style_none, text=str.tostring(hhigh), textcolor=color1)
var label lowlabel = label.new(x1Value, hlow, style=label.style_none, text=str.tostring(hlow), textcolor=color1)

if hhigh != hhigh[1] or hlow != hlow[1]
    if not showhist
        line.delete(highline)
        line.delete(lowline)
        label.delete(highlabel)
        label.delete(lowlabel)

    highline := line.new(bar_index, hhigh, bar_index + 1, hhigh, color=color1, style=linestyle1, width=lwidth)
    lowline := line.new(bar_index, hlow, bar_index + 1, hlow, color=color1, style=linestyle1, width=lwidth)
    if showlabel
        highlabel := label.new(x1Value, hhigh, style=label.style_none, text=str.tostring(hhigh), textcolor=color1)
        lowlabel := label.new(x1Value, hlow, style=label.style_none, text=str.tostring(hlow), textcolor=color1)
        label.set_y(highlabel, hhigh)
        label.set_y(lowlabel, hlow)
        label.set_text(highlabel, str.tostring(hhigh) + '-(1.0)')
        label.set_text(lowlabel, str.tostring(hlow) + '-(0.0)')

label.set_x(highlabel, x1Value)
label.set_x(lowlabel, x1Value)

line.set_x2(highline, bar_index + 1)
line.set_x2(lowline, bar_index + 1)

if not showlabel
    label.delete(highlabel)
    label.delete(lowlabel)

if hhigh != hhigh[1] or hlow != hlow[1]
    if not showhist and array.size(lines) > 0
        for i = 0 to array.size(lines) - 1 by 1
            line.delete(array.get(lines, i))
            label.delete(array.get(labels, i))
    array.clear(lines)
    array.clear(labels)
    for i = 1 to lineCount by 1
        shigh = zerolevel + i * range1
        slow = zerolevel - i * range1

        if i != division
            array.push(lines, line.new(bar_index, shigh, bar_index + 1, shigh, color=color1, style=linestyle1, width=lwidth))
            array.push(labels, label.new(bar_index, shigh, text=str.tostring(shigh), textcolor=showlabel ? color1 : color.new(color1, 100), style=label.style_none))

        array.push(lines, line.new(bar_index, slow, bar_index + 1, slow, color=color1, style=linestyle1, width=lwidth))
        array.push(labels, label.new(bar_index, slow, text=str.tostring(slow), textcolor=showlabel ? color1 : color.new(color1, 100), style=label.style_none))

if array.size(lines) > 0
    for i = 0 to array.size(lines) - 1 by 1
        line.set_x2(array.get(lines, i), bar_index + 1)
        label.set_x(array.get(labels, i), x1Value)