Fib Signals [MAT.SO]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © JoshuaDanford

//@version=5

indicator("Fib Signals [MAT.SO]", overlay = true)

startTime = input.time(timestamp("01 Jan 2021 00:00 +0000"), "Bar", confirm = true, group = "Range")
stopTime = input.time(timestamp("01 Jan 2021 00:00 +0000"), "Bar", confirm = true, group = "Range")

mode = input.string("WMA", "Signal Mode", options = ["OHLC", "SMA", "EMA", "WMA"])
modePeriod = input.int(10, "Signal Period (No effect on OHLC mode.")
plotModeValue = input.bool(true, "Plot Mode Value")

show1 = input(title='Show', defval=true, group = "FibLevel1")
fibLevel1 = input.float(title='Fib %', defval=0.000, minval=0, group = "FibLevel1")
show2 = input(title='Show', defval=true, group = "FibLevel2")
fibLevel2 = input.float(title='Fib %', defval=0.236, minval=0, group = "FibLevel2")
show3 = input(title='Show', defval=true, group = "FibLevel3")
fibLevel3 = input.float(title='Fib %', defval=0.382, minval=0, group = "FibLevel3")
show4 = input(title='Show', defval=false, group = "FibLevel4")
fibLevel4 = input.float(title='Fib %', defval=0.500, minval=0, group = "FibLevel4")
show5 = input(title='Show', defval=true, group = "FibLevel5")
fibLevel5 = input.float(title='Fib %', defval=0.618, minval=0, group = "FibLevel5")
show6 = input(title='Show', defval=true, group = "FibLevel6")
fibLevel6 = input.float(title='Fib %', defval=0.786, minval=0, group = "FibLevel6")
show7 = input(title='Show', defval=true, group = "FibLevel7")
fibLevel7 = input.float(title='Fib %', defval=1.000, minval=0, group = "FibLevel7")
show8 = input(title='Show', defval=true, group = "FibLevel8")
fibLevel8 = input.float(title='Fib %', defval=1.272, minval=0, group = "FibLevel8")
show9 = input(title='Show', defval=true, group = "FibLevel9")
fibLevel9 = input.float(title='Fib %', defval=1.414, minval=0, group = "FibLevel9")
show10 = input(title='Show', defval=true, group = "FibLevel10")
fibLevel10 = input.float(title='Fib %', defval=-0.272, minval=0, group = "FibLevel10")
show11 = input(title='Show', defval=true, group = "FibLevel11")
fibLevel11 = input.float(title='Fib %', defval=-0.414, minval=0, group = "FibLevel11")
show12 = input(title='Show', defval=true, group = "FibLevel12")
fibLevel12 = input.float(title='Fib %', defval=-0.618, minval=0, group = "FibLevel12")
show13 = input(title='Show', defval=true, group = "FibLevel13")
fibLevel13 = input.float(title='Fib %', defval=-1.000, minval=0, group = "FibLevel13")

bool withinRange = 0
withinRange := time >= startTime and time <= stopTime ? 1 : 0

bool pastRange = 0
pastRange := time >= stopTime ? 1 : 0

float highest = na
float lowest = na

highest := withinRange ? high > highest[1] ? high : nz(highest[1]) : pastRange ? highest[1] : na
lowest := withinRange ? low < lowest[1] ? low : nz(lowest[1], 999999) : pastRange ? lowest[1] : na

getFib(ratio) =>
    highest - (highest - lowest) * ratio

fibInputs = 13
fibs = array.from(fibLevel1, fibLevel2, fibLevel3, fibLevel4, fibLevel5, fibLevel6, fibLevel7, fibLevel8, fibLevel9, fibLevel10, fibLevel11, fibLevel12, fibLevel13)
showFibs = array.from(show1, show2, show3, show4, show5, show6, show7, show8, show9, show10, show11, show12, show13)
fibValues = array.new_float(13, na)

buySignal = 0
sellSignal = 0

modeValue = close
if (mode == "SMA")
    modeValue := ta.sma(modeValue, modePeriod)
else if (mode == "EMA")
    modeValue := ta.ema(modeValue, modePeriod)
else if (mode == "WMA")
    modeValue := ta.wma(modeValue, modePeriod)
    
plot(plotModeValue ? modeValue : na)

for int i = 0 to 12
    showFib = array.get(showFibs, i)
    fibLevel = array.get(fibs, i)
    fibValue = (pastRange and showFib) ?  getFib(fibLevel) : na
    array.set(fibValues, i, fibValue)
    
    if (mode == "OHLC")
        if (low < fibValue and open > fibValue and close > fibValue)
            buySignal := 1
        if (high > fibValue and open < fibValue and close < fibValue)
            sellSignal := 1
        if (open > fibValue and close < fibValue)
            sellSignal := 1
        if (open < fibValue and close > fibValue)
            buySignal := 1
    else
        if (modeValue > fibValue and modeValue[1] < fibValue)
            buySignal := 1
        if (modeValue < fibValue and modeValue[1] > fibValue)
            sellSignal := 1
        if (low < fibValue and modeValue > fibValue and close > fibValue and modeValue > modeValue[1])
            buySignal := 1
        if (high > fibValue and modeValue < fibValue and close < fibValue and modeValue < modeValue[1])
            sellSignal := 1

plotshape(buySignal, title="Long", text="Long", textcolor=color.new(color.white, 0), style=shape.labelup, location=location.belowbar, color=color.new(color.green, 0), size=size.tiny)
plotshape(sellSignal, title="Short", text="Short", textcolor=color.new(color.white, 0), style=shape.labeldown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny)

index = 0
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))
index += 1
plot(array.get(fibValues, index))