Fibonacci Ratios [theEccentricTrader]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © theEccentricTrader
//@version=5


indicator('Fibonacci Ratios [theEccentricTrader]', overlay = true)


//////////// shsl //////////// 


shPrice = close[1] >= open[1] and close < open and high >= high[1] and barstate.isconfirmed ? high : 
 close[1] >= open[1] and close < open and high <= high[1] and barstate.isconfirmed ? high[1] : na
slPrice = close[1] < open[1] and close >= open and low <= low[1] and barstate.isconfirmed ? low : 
 close[1] < open[1] and close >= open and low >= low[1] and barstate.isconfirmed ? low[1] : na
peak = ta.valuewhen(shPrice, shPrice, 0)
trough = ta.valuewhen(slPrice, slPrice, 0)
shCloseBarIndex = ta.valuewhen(shPrice, bar_index, 0)
slCloseBarIndex = ta.valuewhen(slPrice, bar_index, 0)


//////////// lines and labels //////////// 


addExtensions = input(defval = true, title = 'Show Fibonacci Extensions', group = "Fibonacci Extensions")

zeroLineColor = input(defval = color.blue, title = '00.0% Color', inline = '1', group = "Line Coloring") 
twoThreeSixLineColor = input(defval = color.green, title = '23.6% Color', inline = '2', group = "Line Coloring")  
threeEightTwoLineColor = input(defval = color.orange, title = '38.2% Color', inline = '3', group = "Line Coloring") 
fiveHundredLineColor = input(defval = color.red, title = '50.0% Color', inline = '4', group = "Line Coloring")  
sixOneEightLineColor = input(defval = color.yellow, title = '61.8% Color', inline = '5', group = "Line Coloring")  
sevenEightSixLineColor = input(defval = color.maroon, title = '78.6% Color', inline = '6', group = "Line Coloring")  
oneHundredLineColor = input(defval = color.purple, title = '100.0% Color', inline = '1', group = "Line Coloring")  
oneSixOneEightLineColor = input(defval = color.yellow, title = '161.8% Color', inline = '2', group = "Line Coloring")  
twoSixOneEightLineColor = input(defval = color.blue, title = '261.8% Color', inline = '3', group = "Line Coloring")  
threeSixOneEightLineColor = input(defval = color.green, title = '361.8% Color', inline = '4', group = "Line Coloring")  
fourTwoThreeSixLineColor = input(defval = color.orange, title = '423.6% Color', inline = '5', group = "Line Coloring")  
fourSixOneEightLineColor = input(defval = color.red, title = '461.8% Color', inline = '6', group = "Line Coloring")

selectExtend = input.string(title = 'Extend Line Type', defval = 'Right', options = ['None', 'Right', 'Left', 'Both'], group = "Line Extension")
extendLines = selectExtend == 'None' ? extend.none : selectExtend == 'Right' ? extend.right : selectExtend == 'Left' ? extend.left : selectExtend == 'Both' ? extend.both : na
symbolRoundNumber = syminfo.mintick >= 0.1 ? 1 : syminfo.mintick == 0.01 ? 2 : syminfo.mintick == 0.001 ? 3 : syminfo.mintick == 0.0001 ? 4 : syminfo.mintick == 0.00001 ? 5 : 
 syminfo.mintick == 0.000001 ? 6 : syminfo.mintick == 0.0000001 ? 7 : syminfo.mintick == 0.00000001 ? 8 : na

addLabels = input(defval = true, title = 'Show Labels', group = "Labels")

labelTextColor = input(defval = color.white, title = 'Label Text Color', group = "Label Coloring")
labelTextOutlineColor = input(defval = color.black, title = 'Label Text Outline Color', group = "Label Coloring")

var zeroLine = line.new(na, na, na, na, color = zeroLineColor, style = line.style_solid, extend = extendLines)
var twoThreeSixLine = line.new(na, na, na, na, color = twoThreeSixLineColor, style = line.style_solid, extend = extendLines)
var threeEightTwoLine = line.new(na, na, na, na, color = threeEightTwoLineColor, style = line.style_solid, extend = extendLines)
var fiftyLine = line.new(na, na, na, na, color = fiveHundredLineColor, style = line.style_solid, extend = extendLines)
var sixOneEightLine = line.new(na, na, na, na, color = sixOneEightLineColor, style = line.style_solid, extend = extendLines)
var sevenEightSixLine = line.new(na, na, na, na, color = sevenEightSixLineColor, style = line.style_solid, extend = extendLines)
var oneHundredLine = line.new(na, na, na, na, color = oneHundredLineColor, style = line.style_solid, extend = extendLines)
var oneSixOneEightLine = line.new(na, na, na, na, color = oneSixOneEightLineColor, style = line.style_solid, extend = extendLines)
var twoSixOneEightLine = line.new(na, na, na, na, color = twoSixOneEightLineColor, style = line.style_solid, extend = extendLines)
var threeSixOneEightLine = line.new(na, na, na, na, color = threeSixOneEightLineColor, style = line.style_solid, extend = extendLines)
var fourTwoThreeSixLine = line.new(na, na, na, na, color = fourTwoThreeSixLineColor, style = line.style_solid, extend = extendLines)
var fourSixOneEightLine = line.new(na, na, na, na, color = fourSixOneEightLineColor, style = line.style_solid, extend = extendLines)

var zeroLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var twoThreeSixLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var threeEightTwoLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var fiftyLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var sixOneEightLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var sevenEightSixLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var oneHundredLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var oneSixOneEightLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var twoSixOneEightLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var threeSixOneEightLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var fourTwoThreeSixLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)
var fourSixOneEightLabel = label.new(na, na, style = label.style_text_outline, color = labelTextOutlineColor, textcolor = labelTextColor, size = size.small)

if slPrice

    line.set_xy1(zeroLine, shCloseBarIndex - 1, trough)
    line.set_xy2(zeroLine, bar_index, trough)
    line.set_xy1(twoThreeSixLine, shCloseBarIndex - 1, trough + (peak - trough) * 0.236)
    line.set_xy2(twoThreeSixLine, bar_index, trough + (peak - trough) * 0.236)
    line.set_xy1(threeEightTwoLine, shCloseBarIndex - 1, trough + (peak - trough) * 0.382)
    line.set_xy2(threeEightTwoLine, bar_index, trough + (peak - trough) * 0.382)
    line.set_xy1(fiftyLine, shCloseBarIndex - 1, trough + (peak - trough) * 0.5)
    line.set_xy2(fiftyLine, bar_index, trough + (peak - trough) * 0.5)
    line.set_xy1(sixOneEightLine, shCloseBarIndex - 1, trough + (peak - trough) * 0.618)
    line.set_xy2(sixOneEightLine, bar_index, trough + (peak - trough) * 0.618)
    line.set_xy1(sevenEightSixLine, shCloseBarIndex - 1, trough + (peak - trough) * 0.786)
    line.set_xy2(sevenEightSixLine, bar_index, trough + (peak - trough) * 0.786)
    line.set_xy1(oneHundredLine, shCloseBarIndex - 1, peak)
    line.set_xy2(oneHundredLine, bar_index, peak)

    line.set_xy1(oneSixOneEightLine, addExtensions ? shCloseBarIndex - 1 : na, addExtensions ? peak + (peak - trough) * 0.618 : na)
    line.set_xy2(oneSixOneEightLine, addExtensions ? bar_index : na, addExtensions ? peak + (peak - trough) * 0.618 : na)
    line.set_xy1(twoSixOneEightLine, addExtensions ? shCloseBarIndex - 1 : na, addExtensions ? peak + (peak - trough) * 1.618 : na)
    line.set_xy2(twoSixOneEightLine, addExtensions ? bar_index : na, addExtensions ? peak + (peak - trough) * 1.618 : na)
    line.set_xy1(threeSixOneEightLine, addExtensions ? shCloseBarIndex - 1 : na, addExtensions ? peak + (peak - trough) * 2.618 : na)
    line.set_xy2(threeSixOneEightLine, addExtensions ? bar_index : na, addExtensions ? peak + (peak - trough) * 2.618 : na)
    line.set_xy1(fourTwoThreeSixLine, addExtensions ? shCloseBarIndex - 1 : na, addExtensions ? peak + (peak - trough) * 3.236 : na)
    line.set_xy2(fourTwoThreeSixLine, addExtensions ? bar_index : na, addExtensions ? peak + (peak - trough) * 3.236 : na)
    line.set_xy1(fourSixOneEightLine, addExtensions ? shCloseBarIndex - 1 : na, addExtensions ? peak + (peak - trough) * 3.618 : na)
    line.set_xy2(fourSixOneEightLine, addExtensions ? bar_index : na, addExtensions ? peak + (peak - trough) * 3.618 : na)

    zeroPrice = line.get_price(zeroLine, bar_index)
    label.set_x(zeroLabel, addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(zeroLabel, addLabels ? trough : na)
    label.set_text(zeroLabel, text = '0.00%\n' + str.tostring(math.round(zeroPrice, symbolRoundNumber)))
    twoThreeSixPrice = line.get_price(twoThreeSixLine, bar_index)
    label.set_x(twoThreeSixLabel, addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(twoThreeSixLabel, addLabels ? trough + (peak - trough) * 0.236 : na)
    label.set_text(twoThreeSixLabel, text = '23.6%\n' + str.tostring(math.round(twoThreeSixPrice, symbolRoundNumber)))
    threeEightTwoPrice = line.get_price(threeEightTwoLine, bar_index)
    label.set_x(threeEightTwoLabel, addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(threeEightTwoLabel, addLabels ? trough + (peak - trough) * 0.382 : na)
    label.set_text(threeEightTwoLabel, text = '38.2%\n' + str.tostring(math.round(threeEightTwoPrice, symbolRoundNumber)))
    fiftyPrice = line.get_price(fiftyLine, bar_index)
    label.set_x(fiftyLabel, addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(fiftyLabel, addLabels ? trough + (peak - trough) * 0.5 : na)
    label.set_text(fiftyLabel, text = '50.0%\n' + str.tostring(math.round(fiftyPrice, symbolRoundNumber)))
    sixOneEightPrice = line.get_price(sixOneEightLine, bar_index)
    label.set_x(sixOneEightLabel, addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(sixOneEightLabel, addLabels ? trough + (peak - trough) * 0.618 : na)
    label.set_text(sixOneEightLabel, text = '61.8%\n' + str.tostring(math.round(sixOneEightPrice, symbolRoundNumber)))
    sevenEightSixPrice = line.get_price(sevenEightSixLine, bar_index)
    label.set_x(sevenEightSixLabel, addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(sevenEightSixLabel, addLabels ? trough + (peak - trough) * 0.786 : na)
    label.set_text(sevenEightSixLabel, text = '78.6%\n' + str.tostring(math.round(sevenEightSixPrice, symbolRoundNumber)))
    oneHundredPrice = line.get_price(oneHundredLine, bar_index)
    label.set_x(oneHundredLabel, addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(oneHundredLabel, addLabels ? peak : na)
    label.set_text(oneHundredLabel, text = '100.0%\n' + str.tostring(math.round(oneHundredPrice, symbolRoundNumber)))

    oneSixOneEightPrice = line.get_price(oneSixOneEightLine, bar_index)
    label.set_x(oneSixOneEightLabel, addExtensions and addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(oneSixOneEightLabel, addExtensions and addLabels ? peak + (peak - trough) * 0.618 : na)
    label.set_text(oneSixOneEightLabel, text = '161.8%\n' + str.tostring(math.round(oneSixOneEightPrice, symbolRoundNumber)))
    twoSixOneEightPrice = line.get_price(twoSixOneEightLine, bar_index)
    label.set_x(twoSixOneEightLabel, addExtensions and addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(twoSixOneEightLabel, addExtensions and addLabels ? peak + (peak - trough) * 1.618 : na)
    label.set_text(twoSixOneEightLabel, text = '261.8%\n' + str.tostring(math.round(twoSixOneEightPrice, symbolRoundNumber)))
    threeSixOneEightPrice = line.get_price(threeSixOneEightLine, bar_index)
    label.set_x(threeSixOneEightLabel, addExtensions and addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(threeSixOneEightLabel, addExtensions and addLabels ? peak + (peak - trough) * 2.618 : na)
    label.set_text(threeSixOneEightLabel, text = '361.8%\n' + str.tostring(math.round(threeSixOneEightPrice, symbolRoundNumber)))
    fourTwoThreeSixPrice = line.get_price(fourTwoThreeSixLine, bar_index)
    label.set_x(fourTwoThreeSixLabel, addExtensions and addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(fourTwoThreeSixLabel, addExtensions and addLabels ? peak + (peak - trough) * 3.236 : na)
    label.set_text(fourTwoThreeSixLabel, text = '423.6%\n' + str.tostring(math.round(fourTwoThreeSixPrice, symbolRoundNumber)))
    fourSixOneEightPrice = line.get_price(fourSixOneEightLine, bar_index)
    label.set_x(fourSixOneEightLabel, addExtensions and addLabels ? shCloseBarIndex - 1 : na)
    label.set_y(fourSixOneEightLabel, addExtensions and addLabels ? peak + (peak - trough) * 3.618 : na)
    label.set_text(fourSixOneEightLabel, text = '461.8%\n' + str.tostring(math.round(fourSixOneEightPrice, symbolRoundNumber)))

if shPrice

    line.set_xy1(zeroLine, slCloseBarIndex - 1, peak)
    line.set_xy2(zeroLine, bar_index, peak)
    line.set_xy1(twoThreeSixLine, slCloseBarIndex - 1, peak - (peak - trough) * 0.236)
    line.set_xy2(twoThreeSixLine, bar_index, peak - (peak - trough) * 0.236)
    line.set_xy1(threeEightTwoLine, slCloseBarIndex - 1, peak - (peak - trough) * 0.382)
    line.set_xy2(threeEightTwoLine, bar_index, peak - (peak - trough) * 0.382)
    line.set_xy1(fiftyLine, slCloseBarIndex - 1, peak - (peak - trough) * 0.5)
    line.set_xy2(fiftyLine, bar_index, peak - (peak - trough) * 0.5)
    line.set_xy1(sixOneEightLine, slCloseBarIndex - 1, peak - (peak - trough) * 0.618)
    line.set_xy2(sixOneEightLine, bar_index, peak - (peak - trough) * 0.618)
    line.set_xy1(sevenEightSixLine, slCloseBarIndex - 1, peak - (peak - trough) * 0.786)
    line.set_xy2(sevenEightSixLine, bar_index, peak - (peak - trough) * 0.786)
    line.set_xy1(oneHundredLine, slCloseBarIndex - 1, trough)
    line.set_xy2(oneHundredLine, bar_index, trough)

    line.set_xy1(oneSixOneEightLine, addExtensions ? slCloseBarIndex - 1 : na, addExtensions ? trough - (peak - trough) * 0.618 : na)
    line.set_xy2(oneSixOneEightLine, addExtensions ? bar_index : na, addExtensions ? trough - (peak - trough) * 0.618 : na)
    line.set_xy1(twoSixOneEightLine, addExtensions ? slCloseBarIndex - 1 : na, addExtensions ? trough - (peak - trough) * 1.618 : na)
    line.set_xy2(twoSixOneEightLine, addExtensions ? bar_index : na, addExtensions ? trough - (peak - trough) * 1.618 : na)
    line.set_xy1(threeSixOneEightLine, addExtensions ? slCloseBarIndex - 1 : na, addExtensions ? trough - (peak - trough) * 2.618 : na)
    line.set_xy2(threeSixOneEightLine, addExtensions ? bar_index : na, addExtensions ? trough - (peak - trough) * 2.618 : na)
    line.set_xy1(fourTwoThreeSixLine, addExtensions ? slCloseBarIndex - 1 : na, addExtensions ? trough - (peak - trough) * 3.236 : na) 
    line.set_xy2(fourTwoThreeSixLine, addExtensions ? bar_index : na, addExtensions ? trough - (peak - trough) * 3.236 : na)
    line.set_xy1(fourSixOneEightLine, addExtensions ? slCloseBarIndex - 1 : na, addExtensions ? trough - (peak - trough) * 3.618 : na) 
    line.set_xy2(fourSixOneEightLine, addExtensions ? bar_index : na, addExtensions ? trough - (peak - trough) * 3.618 : na)

    zeroPrice = line.get_price(zeroLine, bar_index)
    label.set_x(zeroLabel, addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(zeroLabel, addLabels ? peak : na)
    label.set_text(zeroLabel, text = '00.0%\n' + str.tostring(math.round(zeroPrice, symbolRoundNumber)))
    twoThreeSixPrice = line.get_price(twoThreeSixLine, bar_index)
    label.set_x(twoThreeSixLabel, addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(twoThreeSixLabel, addLabels ? peak - (peak - trough) * 0.236 : na)
    label.set_text(twoThreeSixLabel, text = '23.6%\n' + str.tostring(math.round(twoThreeSixPrice, symbolRoundNumber)))
    threeEightTwoPrice = line.get_price(threeEightTwoLine, bar_index)
    label.set_x(threeEightTwoLabel, addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(threeEightTwoLabel, addLabels ? peak - (peak - trough) * 0.382 : na)
    label.set_text(threeEightTwoLabel, text = '38.2%\n' + str.tostring(math.round(threeEightTwoPrice, symbolRoundNumber)))
    fiftyPrice = line.get_price(fiftyLine, bar_index)
    label.set_x(fiftyLabel, addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(fiftyLabel, addLabels ? peak - (peak - trough) * 0.5 : na)
    label.set_text(fiftyLabel, text = '50.0%\n' + str.tostring(math.round(fiftyPrice, symbolRoundNumber)))
    sixOneEightPrice = line.get_price(sixOneEightLine, bar_index)
    label.set_x(sixOneEightLabel, addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(sixOneEightLabel, addLabels ? peak - (peak - trough) * 0.618 : na)
    label.set_text(sixOneEightLabel, text = '61.8%\n' + str.tostring(math.round(sixOneEightPrice, symbolRoundNumber)))
    sevenEightSixPrice = line.get_price(sevenEightSixLine, bar_index)
    label.set_x(sevenEightSixLabel, addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(sevenEightSixLabel, addLabels ? peak - (peak - trough) * 0.786 : na)
    label.set_text(sevenEightSixLabel, text='78.6%\n' + str.tostring(math.round(sevenEightSixPrice, symbolRoundNumber)))
    oneHundredPrice = line.get_price(oneHundredLine, bar_index)
    label.set_x(oneHundredLabel, addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(oneHundredLabel, addLabels ? trough : na)
    label.set_text(oneHundredLabel, text = '100.0%\n' + str.tostring(math.round(oneHundredPrice, symbolRoundNumber)))

    oneSixOneEightPrice = line.get_price(oneSixOneEightLine, bar_index)
    label.set_x(oneSixOneEightLabel, addExtensions and addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(oneSixOneEightLabel, addExtensions and addLabels ? trough - (peak - trough) * 0.618 : na)
    label.set_text(oneSixOneEightLabel, text = '161.8%\n' + str.tostring(math.round(oneSixOneEightPrice, symbolRoundNumber)))
    twoSixOneEightPrice = line.get_price(twoSixOneEightLine, bar_index)
    label.set_x(twoSixOneEightLabel, addExtensions and addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(twoSixOneEightLabel, addExtensions and addLabels ? trough - (peak - trough) * 1.618 : na)
    label.set_text(twoSixOneEightLabel, text = '261.8%\n' + str.tostring(math.round(twoSixOneEightPrice, symbolRoundNumber)))
    threeSixOneEightPrice = line.get_price(threeSixOneEightLine, bar_index)
    label.set_x(threeSixOneEightLabel, addExtensions and addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(threeSixOneEightLabel, addExtensions and addLabels ? trough - (peak - trough) * 2.618 : na)
    label.set_text(threeSixOneEightLabel, text = '361.8%\n' + str.tostring(math.round(threeSixOneEightPrice, symbolRoundNumber)))
    fourTwoThreeSixPrice = line.get_price(fourTwoThreeSixLine, bar_index)
    label.set_x(fourTwoThreeSixLabel, addExtensions and addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(fourTwoThreeSixLabel, addExtensions and addLabels ? trough - (peak - trough) * 3.236 : na)
    label.set_text(fourTwoThreeSixLabel, text = '423.6%\n' + str.tostring(math.round(fourTwoThreeSixPrice, symbolRoundNumber)))
    fourSixOneEightPrice = line.get_price(fourTwoThreeSixLine, bar_index)
    label.set_x(fourSixOneEightLabel, addExtensions and addLabels ? slCloseBarIndex - 1 : na)
    label.set_y(fourSixOneEightLabel, addExtensions and addLabels ? trough - (peak - trough) * 3.618 : na)
    label.set_text(fourSixOneEightLabel, text = '461.8%\n' + str.tostring(math.round(fourSixOneEightPrice, symbolRoundNumber)))

