INEVITRADE Pro +
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jojou
//@version=5
// RSI+ Open source

indicator(title="INEVITRADE Pro +", shorttitle="INEVITRADE Pro +", format=format.price, precision=1)

ma(source, length, type) =>
    switch type
        "EMA" => ta.ema(source, length)

// ————— Inputs
rsiLengthInput = input.int(14, minval=1, title="RSI Length")
rsiSourceInput = input.source(close, "Source")

rsiC1Input = input.color(#64ffda, title="Color 1")
rsiC2Input = input.color(#F43E32, title="Color 2")
rsiBandColorInput = input.color(color.rgb(230, 230, 230, 90), title="RSI Band Color")

showBand = input(true, title="Highlight RSI Overbought/Oversold")
showCloud = input(true, title="Show RSI Cloud")
showFlagCloudFlip = input(false, title="Flag Cloud Flip")

rsiExtendedUpperBand = input.int(75, minval=1, title="Extended Upper Band")
rsiUpperBand = input.int(70, minval=1, title="Upper Band")
rsiLowerBand = input.int(30, minval=1, title="Lower Band")
rsiExtendedLowerBand = input.int(25, minval=1, title="Extended Lower Band")

up = ta.rma(math.max(ta.change(rsiSourceInput), 0), rsiLengthInput)
down = ta.rma(-math.min(ta.change(rsiSourceInput), 0), rsiLengthInput)
rsi = ((down == 0) ? 100 : up == 0) ? 0 : 100 - (100 / (1 + up / down))

rsiEMA = ma(rsi, rsiLengthInput, "EMA")
previousRSI = rsi[1]
previousRSIEMA = rsiEMA[1]

// RSI Colours
rsiColour = rsi >= rsiEMA ? rsiC1Input : rsiC2Input
flagColour = (rsi > rsiEMA and previousRSI < previousRSIEMA) ? rsiC1Input : (rsi < rsiEMA and previousRSI > previousRSIEMA ? rsiC2Input : na)

// RSI Plots
rsiPlot = plot(rsi, title="RSI", color=rsiColour)
rsiEMAPlot = plot(showCloud ? rsiEMA : na, title="RSI EMA", editable=false, display=display.none)

// RSI Flag Cloud Flip
flagCloudFlip = (rsi > rsiEMA and previousRSI < previousRSIEMA) ? rsiEMA : (rsi < rsiEMA and previousRSI > previousRSIEMA ? rsiEMA : na)
plot(showFlagCloudFlip ? flagCloudFlip : na, title="Flag Cloud Flip", color=color.new(flagColour, 20), linewidth=3, style=plot.style_circles, editable=false)

// RSI Highlights
bgcolor(rsi >= rsiUpperBand ? color.new(rsiC1Input, 90) : na, title="Overbought Highlight")
bgcolor(rsi >= rsiExtendedUpperBand ? color.new(rsiC1Input, 90) : na, title="Extended Overbought Highlight")
bgcolor(rsi <= rsiLowerBand ? color.new(#F43E32, 85) : na, title="Oversold Highlight")
bgcolor(rsi <= rsiExtendedLowerBand ? color.new(#F43E32, 85) : na, title="Extended Oversold Highlight")

// RSI EMA Cloud
fill(rsiPlot, rsiEMAPlot, color=color.new(rsiColour, 70), title="RSI Cloud")

// RSI Baseline
hline(50, "Baseline", color=color.new(#787B86, 50), linestyle=hline.style_solid)

// RSI Overbought & Oversold
fill(hline(showBand ? rsiUpperBand : na, editable=false, display=display.none), hline(showBand ? rsiExtendedUpperBand : na, editable=false, display=display.none), color=rsiBandColorInput, title="Overbought Fill")
fill(hline(showBand ? rsiLowerBand : na, editable=false, display=display.none), hline(showBand ? rsiExtendedLowerBand : na, editable=false, display=display.none), color=rsiBandColorInput, title="Oversold Fill")

// Strength vs BTC
btc = input.symbol("BYBIT:BTCUSDT", title = "Compare To", group="Strength vs BTC Settings")
period = input("5", title = "timeframe")
candleAmount = input(100,title = "Number Of Candles to Include in Avg." )
upColor = input(color.green, title = "Up Color")
downColor = input(color.red, title = "Down Color")

float candleSum = 0
float candleAvg = 0
float btcCandleSum = 0
float btcCandleAvg = 0

float lowCandleSum = 0
float lowCandleAvg = 0
float lowBtcCandleSum = 0
float lowBtcCandleAvg = 0

thisHigh = request.security(syminfo.tickerid, period, high)
btcHigh = request.security(btc, period, high)
btcLow = request.security(btc, period, low)

ticker = syminfo.tickerid

// get ticker
getPair(_str, _n) =>
    string[] _pair = str.split(_str, ":")
    string[] _chars = str.split(array.get(_pair, 1), "")
    int _len = array.size(_chars)
    int _end = math.min(_len, math.max(0, _n))
    string[] _substr = array.new_string(0)
    if _end <= _len
        _substr := array.slice(_chars, 0, _end)
    string _return = array.join(_substr, "")
    
// normalize series within range
normalize(_src, _min, _max) =>
    // Normalizes series with unknown min/max using historical min/max.
    // _src      : series to rescale.
    // _min, _min: min/max values of rescaled series.
    var _historicMin =  10e10
    var _historicMax = -10e10
    _historicMin := math.min(nz(_src, _historicMin), _historicMin)
    _historicMax := math.max(nz(_src, _historicMax), _historicMax)
    _min + (_max - _min) * (_src - _historicMin) / math.max(_historicMax - _historicMin, 10e-10)

for i=1 to candleAmount
    candleSum:= candleSum + thisHigh[i]
    btcCandleSum:= btcCandleSum + btcHigh[i]
    if i == candleAmount
        candleAvg:= candleSum / candleAmount
        btcCandleAvg:= btcCandleSum / candleAmount
        
pairPCT = (thisHigh - candleAvg) / thisHigh
btcPCT = (btcHigh - btcCandleAvg) / btcHigh

plotColor = color.white

multiplier = str.tonumber(period)
plotPCT = ((multiplier * pairPCT - multiplier * btcPCT) * 100 + 135)


if plotPCT < 135
    plotColor := downColor
if plotPCT > 135
    plotColor := upColor
if getPair(ticker, 3) == "BTC"
    plotColor:=color(na)

// plot(135, color=color.gray)

plot(normalize(plotPCT, 90, 180), "Normalized Strength vs BTC", color=plotColor)

hline(180)
hline(90)
