Squeeze + ADX + RSI + Stochastic RSI [Bybit en Español]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Bybit Embajador de la Comunidad en Español: matetaronna

//@version=4
study(title="Squeeze + ADX + RSI + Stochastic RSI + MFI [Matt]", shorttitle="[All-In-One Indicator]", overlay=false)

//***************************************************************************************************************************************************************************************//

// Colors
colorRed = #ff0000
colorPurple = #e600e6
colorGreen = #3fff00
colorOrange = #e2a400
colorYellow = #ffe500
colorWhite = #ffffff
colorPink = #ff00f0
colorBluelight = #31c0ff


//***************************************************************************************************************************************************************************************//

//RSI
show_RSI = input(true, title="----------- Mostrar RSI-StochRSI-BB -----------", group="RSI-StochRSI-BB")
int rsiLengthInput = input(5,    title="RSI Longitud", minval=1, step=1, group="RSI")
rsiSourceInput = input(close, title="RSI Fuente", type=input.source, group="RSI")
up = rma(max(change(rsiSourceInput), 0), rsiLengthInput)
down = rma(-min(change(rsiSourceInput), 0), rsiLengthInput)
rsi_x = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
//plot(rsi, "RSI", color=#7E57C2)

//STOCH RSI
smoothK = 3
smoothD = 3
lengthRSI = 14
lengthStoch = 14
rsi1 = rsi(close, lengthRSI)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

//BB
lengthBB = input(20, minval=1)
srcBB = input(close, title="Source", group="BB")
multBB = input(2.0, minval=0.001, maxval=50, title="StdDev", group="BB")
basisBB = sma(srcBB, lengthBB)
devBB = multBB * stdev(srcBB, lengthBB)
upperBB = basisBB + devBB
lowerBB = basisBB - devBB

//RSI + MFI
rsiMFIShow0 = input(true, title = "----------- Mostrar RSI-MFI (Barra) -----------", type = input.bool, group="RSI-MFI")
rsiMFIShow = input(true, title = "----------- Mostrar RSI-MFI -----------", type = input.bool, group="RSI-MFI")
rsiMFIperiod = input(60,title = 'MFI Period', type = input.integer, group="RSI-MFI")
rsiMFIMultiplier = input(380, title = 'MFI Area multiplier', type = input.float, group="RSI-MFI")
rsiMFIPosY = input(2.5, title = 'MFI Area Y Pos', type = input.float, group="RSI-MFI")
f_rsimfi(_period, _multiplier, _tf) => security(syminfo.tickerid, _tf, sma(((close - open) / (high - low)) * _multiplier, _period) - rsiMFIPosY)
rsiMFI = f_rsimfi(rsiMFIperiod, rsiMFIMultiplier, timeframe.period)
rsiMFIColor = rsiMFI > 0 ? #3ee145 : #ff3d2e

//****************************************************************************************************************************************************************************************//


// Squeeze Momentum
show_Momen = input(true, title="----------- Mostrar Squeeze Momentum -----------", group="Squeeze Momentum")
int lengthM = input(20,    title="MOM Longitud", minval=1, step=1, group="Squeeze Momentum")
srcM = input(close, title="MOM Fuente", type=input.source, group="Squeeze Momentum")
int length = input(20,    title="SQZ Longitud",  minval=1, step=1, group="Squeeze Momentum")
src = input(close, title="SQZ Fuente",  type=input.source, group="Squeeze Momentum")
color_bool = input(false, title="----------- Colores Originales -----------", group="Squeeze Momentum")

// Momentum
sz  = linreg(srcM - avg(avg(highest(high, lengthM), lowest(low, lengthM)), sma(close, lengthM)), lengthM, 0)

// Condiciones del momento para elegir el color
sc1 = sz >= 0
sc2 = sz < 0
sc3 = sz >= sz[1]
sc4 = sz < sz[1]

// Asignamos el color final
colorSQ1 = color_bool ? #008000 : #90caf9 
colorSQ2 = color_bool ? #00ff00 : #0d47a1
colorSQ3 = color_bool ? #800000 : #90caf9 
colorSQ4 = color_bool ? #ff0000 : #0d47a1
colorSQ2_ = #131722
clr = sc1 and sc3 ? colorSQ2 : sc1 and sc4 ? colorSQ1 : sc2 and sc4 ? colorSQ4 : sc2 and sc3 ? colorSQ3 : color.gray

// Calculate BB
multKC = 1.5
source = close
basis = sma(source, lengthM)
dev = multKC * stdev(source, lengthM)
//upperBB = basis + dev
//lowerBB = basis - dev

// Calculate KC
lengthKC=20
ma = sma(source, lengthKC)
range = tr
rangema = sma(range, lengthKC)
upperKC = ma + rangema * multKC
lowerKC = ma - rangema * multKC

sqzOn  = (lowerBB > lowerKC) and (upperBB < upperKC)
sqzOff = (lowerBB < lowerKC) and (upperBB > upperKC)
noSqz  = (sqzOn == false) and (sqzOff == false)

val = linreg(source  -  avg(avg(highest(high, lengthKC), lowest(low, lengthKC)),sma(close,lengthKC)), lengthKC,0)

bcolor = iff( val > 0, iff( val > nz(val[1]), color.lime, color.green), iff( val < nz(val[1]), color.red, color.maroon))
scolor = noSqz ? color.blue : sqzOn ? color.yellow : color.gray 
show_SQZ = input(true, title="----------- Mostrar Compresion de Bandas -----------")

//Abreviamos en variables los colores que utilizamos
openLongC = bcolor == color.lime
closeLongC = bcolor == color.green and bcolor[1] == color.green
closeLongC1W = bcolor == color.green
openShortC = bcolor == color.red
closeShortC = bcolor == color.maroon and bcolor[1] == color.maroon
closeShortC1W = bcolor == color.maroon

//****************************************************************************************************************************************************************************************//

// ADX

// Variables extra
int scale = 75
useTrueRange = true
show_ADX = input(true, title="----------- Mostrar ADX -----------", group="ADX")
scaleADX = 2
int far = input(-3, title="Desfase del ADX", minval=-10, step=1, group="ADX")
int adxlen = input(14, title="ADX Longitud", minval=1, step=1, group="ADX")
int dilen = input(14, title="DI Longitud", minval=1, step=1, group="ADX")
keyLevel = input(23, title="Key Level", minval=1, step=1, group="ADX")

// Operaciones del ADX en si
dirmov(len) =>
	up = change(high)
	down = -change(low)
	truerange = rma(tr, len)
	plus = fixnan(100 * rma(up > down and up > 0 ? up : 0, len) / truerange)
	minus = fixnan(100 * rma(down > up and down > 0 ? down : 0, len) / truerange)
	[plus, minus]

adx(dilen, adxlen) => 
	[plus, minus] = dirmov(dilen)
	sum = plus + minus
	adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)
	[adx, plus, minus]

// Valor final del ADX
[adxValue, diplus, diminus] = adx(dilen, adxlen)

// Calculamos el scale del ADX respecto a los otros indicadores
biggest(series) =>
    max = 0.0
    max := nz(max[1], series)
    if series > max
        max := series
    max

ni = biggest(sz)
far1=far* ni/scale
adx_scale = (adxValue - keyLevel) * ni/scale
adx_scale2 = (adxValue - keyLevel+far) * ni/scale

//Variables de fuerza utilizadas en el calculo de las posiciones
adxForce = adxValue > adxValue[1] and adxValue < 35
adxNoForce = adxValue < adxValue[1] and adxValue[1] < adxValue[2]
adxNoForce1W = adxValue < adxValue[1]

//****************************************************************************************************************************************************************************************//


// Plot de todo

// RSI + MFI
// Barra de Abajo
zLine = plot(0, color = color.new(colorWhite, 100))
rsiMfiBarTopLine = plot(rsiMFIShow0 ? -55 * (ni/scale) : na, title = 'MFI Bar TOP Line', color = color.new(colorWhite, 100))
rsiMfiBarBottomLine = plot(rsiMFIShow0 ? -59 * (ni/scale) : na, title = 'MFI Bar BOTTOM Line', color = color.new(colorWhite, 100))
fill(rsiMfiBarTopLine, rsiMfiBarBottomLine, title = 'MFI Bar Colors', color = color.new(rsiMFIColor, 75))
// Ondas
rsiMFIplot = plot(rsiMFIShow ? rsiMFI * (ni/scale) : na, title = 'RSI+MFI Area', color = color.new(rsiMFIColor, 75))
fill(rsiMFIplot, zLine, color = color.new(rsiMFIColor, 70))

//ADX
plot(show_ADX ? far1 * scaleADX : na, color=color.white, title="KeyLevel", linewidth = 1)
p1 = plot(show_ADX ? adx_scale2 * scaleADX : show_ADX ? adx_scale * scaleADX : na, color = color.purple, title = "ADX", linewidth = 2)

// RSI + STOCHASTIC
plotchar(show_RSI and d < 30 and rsi_x < 30 and close < lowerBB and rsiMFI < 0  ? -40 * (ni/scale) : na, title = 'Buy circle', char='•', color = color.new(colorGreen, 50), location = location.absolute, size = size.small)
plotchar(show_RSI and d > 70 and rsi_x > 70 and close > upperBB and rsiMFI > 0  ? 40 * (ni/scale) : na, title = 'Sell circle', char='•', color = color.new(colorRed, 50), location = location.absolute, size = size.small)

// SQUEEZE
plot(show_Momen ? sz * 1.5 : na, title = "Momentum", color = color.new(clr, 0), style=plot.style_area, linewidth = 4)
plot(show_SQZ ? 0 : na, title = "Squeeze", color = color.new(scolor, 0), style=plot.style_circles, linewidth=1)

//****************************************************************************************************************************************************************************************//

// Divergencias
show_div=input(true,title="-------- Divergencias --------", group="Divergencias [Monitor]")
lbR = input(title="Pivot Lookback Right", defval=1, group="Divergencias [Monitor]")
lbL = input(title="Pivot Lookback Left", defval=1, group="Divergencias [Monitor]")
rangeUpper = input(title="Max of Lookback Range", defval=60, group="Divergencias [Monitor]")
rangeLower = input(title="Min of Lookback Range", defval=1, group="Divergencias [Monitor]")
plotBull = input(title="Plot Bullish", defval=true, group="Divergencias [Monitor]")
plotBear = input(title="Plot Bearish", defval=true, group="Divergencias [Monitor]")


bearColor = #ff0000
bullColor = #1bff00 
hiddenBullColor =  #a4ff99 
hiddenBearColor = #ff9e9e
textColor = color.white
noneColor = color.new(color.white, 100)

// Funciones
plFound(osc) => na(pivotlow(osc, lbL, lbR)) ? false : true
phFound(osc) => na(pivothigh(osc, lbL, lbR)) ? false : true

_inRange(cond) =>
    bars = barssince(cond == true)
    rangeLower <= bars and bars <= rangeUpper
    
    
_findDivRB(osc)=>

    // Osc: Higher Low
    oscHL = osc[lbR] > valuewhen(plFound(osc), osc[lbR], 1) and _inRange(plFound(osc)[1])

    // Price: Lower Low
    priceLL = low[lbR] < valuewhen(plFound(osc), low[lbR], 1)

    bullCond = plotBull and priceLL and oscHL and plFound(osc)


    //------------------------------------------------------------------------------
    // Regular Bearish

    // Osc: Lower High
    oscLH = osc[lbR] < valuewhen(phFound(osc), osc[lbR], 1) and _inRange(phFound(osc)[1])

    // Price: Higher High
    priceHH = high[lbR] > valuewhen(phFound(osc), high[lbR], 1)

    bearCond = plotBear and priceHH and oscLH and phFound(osc)
    
    [bullCond,bearCond]
    



[sz_bullCond,sz_bearCond]=_findDivRB(sz)


foundDivBSZ = plFound(sz) and show_Momen and show_div ? true : false 
colordivBSZ = sz_bullCond ? bullColor : noneColor
foundDivBeSZ = phFound(sz)  and show_Momen and show_div ? true : false
colordivBeSZ = sz_bearCond ? bearColor : noneColor



plot(
	 foundDivBSZ ? sz[lbR]* 1.5 : na,
	 offset=-lbR,
	 title="Regular Bullish",
	 linewidth=1,
	 color=colordivBSZ,
	 transp=0
	 )
plot(
	 foundDivBeSZ ? sz[lbR]* 1.5 : na,
	 offset=-lbR,
	 title="Regular Bullish",
	 linewidth=1,
	 color=colordivBeSZ,
	 transp=0
	 )


//****************************************************************************************************************************************************************************************//


// Informacion del Indicador

// Tendencia General

//Esta funcion nos permite llamar a security() sin problemas
f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on)

//Diferenciamos y marcamos una tendencia bien definida, nos enfocamos en los graficos mas a largo plazo
ema25 = ema(close, 25)
ema55 = ema(close, 55)
ema200 = ema(close, 200)


//RSI
rsiStory = f_secureSecurity(syminfo.tickerid, "D", close) > f_secureSecurity(syminfo.tickerid, "D", ema200) ? (f_secureSecurity(syminfo.tickerid, "D", rsi_x < 40) and f_secureSecurity(syminfo.tickerid, "240", rsi_x < 40) ? "RSI -> STRONG BUY [BULL]" : f_secureSecurity(syminfo.tickerid, "D", rsi_x > 75) and f_secureSecurity(syminfo.tickerid, "240", rsi_x > 75) ? "RSI -> STRONG SELL [BULL]" : "RSI --> NADA") : f_secureSecurity(syminfo.tickerid, "D", close) < f_secureSecurity(syminfo.tickerid, "D", ema200) ? (f_secureSecurity(syminfo.tickerid, "D", rsi_x < 25) and f_secureSecurity(syminfo.tickerid, "240", rsi_x < 25) ? "RSI -> STRONG BUY [BEAR]" : f_secureSecurity(syminfo.tickerid, "D", rsi_x > 60) and f_secureSecurity(syminfo.tickerid, "240", rsi_x > 60) ? "RSI -> STRONG SELL [BEAR]" : "RSI --> NADA") : "RSI --> NADA"

//BullTrend
//longTrend1W = f_secureSecurity(syminfo.tickerid, "1W", (closeShortC1W and adxNoForce1W) or openLongC)
longTrend1D = f_secureSecurity(syminfo.tickerid, "D", (closeShortC and (adxNoForce or adxValue < 23)) or (openLongC and adxForce))
longTrend4HR = f_secureSecurity(syminfo.tickerid, "240", close > ema25)
BullTrend = (longTrend1D and longTrend4HR)

//BearTrend
shortTrend1D = f_secureSecurity(syminfo.tickerid, "D", (closeLongC) or (openShortC and adxForce))
shortTrend4HR = f_secureSecurity(syminfo.tickerid, "240", low < ema55)
BearTrend = (shortTrend1D and shortTrend4HR)

//NeutralTrend
NeutralTrend = not BullTrend and not BearTrend

trend = BearTrend ? "BAJISTA" : BullTrend ? "ALCISTA" : NeutralTrend ? "NEUTRAL"  : na


//ATR calculation for stoplosses
atrValue = rma(tr, 14)
stopLong = tostring(lowest(low, 14) - atrValue, "#.####")
stopShort = tostring(highest(high, 14) + atrValue, "#.####")

//Inputs
show_status = input(true, title = "----------- Mostrar Status ------------", group="General")
dist= input(10,title="Distancia del monitor", group="General")
dashColor = input(color.new(#696969, 90), "label Color", inline="Dash Line", group="General")
dashTextColor = input(color.new(#ffffff, 0), "Text Color", inline="Dash Line", group="General")


if(adxValue > adxValue[1] and adxValue > 23)
    iadx='ADX con pendiente positiva por encima punto 23'
if(adxValue > adxValue[1] and adxValue < 23)
    iadx='ADX con pendiente positiva por debajo punto 23'
if(adxValue < adxValue[1] and adxValue < 23)
    iadx='ADX con pendiente negativa por debajo punto 23'
if(adxValue < adxValue[1] and adxValue > 23)
    iadx='ADX con pendiente negativa por encima punto 23'


a1=adxValue >= 23
a2=adxValue < 23
a3=adxValue >= adxValue[1]
a4=adxValue < adxValue[1]


iAdx = a1 and a3 ? 'Pendiente positiva ↑ 23' : a1 and a4 ? 'Pendiente negativa ↑ 23' : 
   a2 and a4 ? 'Pendiente negativa ↓ 23' : a2 and a3 ? 'Pendiente positiva ↓ 23' : '-'
   
   
iMom = sc1 and sc3 ? 'Direccionalidad alcista' : sc1 and sc4 ? 'Direccionalidad bajista' : 
   sc2 and sc4 ? 'Direccionalidad bajista' : sc2 and sc3 ? 'Direccinalidad alcista' : '-'
   
   
igral = a1 and a3 and sc1 and sc3 ? 'Fuerte movimiento alcista' : a1 and a3 and sc1 and sc4 ?  'Monitor muestra rango-caida pero\nel movimiento tiene fuerza':
 a1 and a3 and sc2 and sc4 ? 'Fuerte movimiento bajista' : a1 and a3 and sc2 and sc3 ?  'Monitor muestra rango-subida pero\nel movimiento tiene fuerza':
 a1 and a4 and sc1 and sc3 ? 'Movimiento alcista sin fuerza' : a1 and a4 and sc1 and sc4 ?  'Monitor muestra rango-caida\n pendiente negativa en ADX ':
 a1 and a4 and sc2 and sc4 ? 'Movimiento bajista sin fuerza' : a1 and a4 and sc2 and sc3 ?  'Monitor muestra rango-subida con \npendiente negativa en ADX ':
 a2 and a4 and sc1 and sc3 ? 'Movimiento alcista sin fuerza' :  a2 and a4 and sc1 and sc4 ?  'Monitor muestra rango-caida sin fuerza ':
 a2 and a4 and sc2 and sc4 ? 'Movimiento bajista sin fuerza' :  a2 and a4 and sc2 and sc3 ?  'Monitor muestra rango-subida sin fuerza ':
 a2 and a3 and sc1 and sc3 ? 'Movimiento alcista que \n quiere agarrar fuerza' : a2 and a3 and sc1 and sc4 ?  'Monitor muestra rango-caida,\n el movimiento quiere agarrar fuerza':
 a2 and a3 and sc2 and sc4 ? 'Movimiento bajista que \n quiere agarrar fuerza' : a2 and a3 and sc2 and sc3 ?  'Monitor muestra rango-subida,\n el movimiento quiere agarrar fuerza': '-'


scr_label='- ADX: '+iAdx+'\n- Monitor: '+iMom+'\n- Overal BIAS: '+igral+"\n"+rsiStory+"\n- SL para Long: "+stopLong+"\n- SL para Short: "+stopShort+"\n- Tendencia General: "+trend


if show_status

    lab_l = label.new(
              bar_index + dist, 0,  scr_label, 
              color     = dashColor, 
              textcolor = dashTextColor, 
              style     = label.style_label_left,
              yloc      = yloc.price,
              size      = size.normal)
    label.delete(lab_l[1])
    
//****************************************************************************************************************************************************************************************//