#// © BalintDavid
#https://www.tradingview.com/script/uHew29m1-RSI-Swing-Indicator-v2/
#study("RSI Swing Indicator" V2.0
# Converted and mod by Sam4Cok@Samer800 - 10/2022
#// RSI Settings for user
input Source = close; # "RSI Source"
input wicks = yes;
input rsiLength = 7; # "RSI Length"
input rsiOverbought = 70;# "RSI Overbought"
input rsiOvesold = 30; # "RSI Oversold"
input OscillatorType = {Default "RSI", "Stochastic RSI"};
input smoothK = 6;
input smoothD = 3;
input lengthStochRSI = 14; # "RSI Length"
input lengthStoch = 9; # "Stochastic Length"
input StochOverbought = 90; # "RSI Overbought"
input StochOvesold = 10; # "RSI Oversold"
input HorizontalLines = yes;
input showBubbles = no;
input ShowZigZag = no;
def na = Double.NaN;
def h = if(wicks,high,close); def l = if(wicks,low,close);
script nz {
input data = 1;
input repl = 0;
def ret_val = if IsNaN(data) then repl else data;
plot return = ret_val;
}
#barssince(Condition) =>
script barssince {
input Condition = 0;
def barssince = if Condition then 1 else barssince[1] + 1;
plot return = barssince;
}
DefineGlobalColor("Unconfirmed", Color.GRAY);
DefineGlobalColor("Up", CreateColor(91,156,246));
DefineGlobalColor("Down", CreateColor(171,71,188));
##### Stochasitc RSI
def StochRSI = rsi(Price = Source, Length = lengthStochRSI);
def stoch = 100 * (StochRSI - lowest(StochRSI, lengthStoch)) / (highest(StochRSI, lengthStoch) - lowest(StochRSI, lengthStoch));
def k = SimpleMovingAvg(stoch, smoothK);
def StochOB = k >= StochOverbought;
def StochOS = k <= StochOvesold;
#// RSI value based on inbuilt RSI
def rsiValue = RSI(Price = Source, Length = rsiLength);
#// Get the current state
def RSIOB = rsiValue >= rsiOverbought;
def RSIOS = rsiValue <= rsiOvesold;
####
def isOverbought = if OscillatorType == OscillatorType."Stochastic RSI" then StochOB else RSIOB;
def isOversold = if OscillatorType == OscillatorType."Stochastic RSI" then StochOS else RSIOS;
def state = {default initialization, overbought, oversold};
def hh;
def ll;
def newMax;
def newMin;
def prevMaxH = hh[1];
def prevMinL = ll[1];
switch (state[1]) {
case initialization:
state = state.overbought;
hh = h;
ll = l;
newMax = na;
newMin = na;
case overbought:
if isOversold {
state = state.oversold;
hh = prevMaxH;
ll = l;
newMax = no;
newMin = yes;
} else {
state = state.overbought;
if h >= prevMaxH and isOverbought {
hh = h;
newMax = yes;
} else {
hh = prevMaxH;
newMax = no;
}
ll = prevMinL;
newMin = no;
}
case oversold:
if isOverbought {
state = state.overbought;
hh = h;
ll = prevMinL;
newMax = yes;
newMin = no;
} else {
state = state.oversold;
if (l <= prevMinL and isOversold) {
ll = l;
newMin = yes;
} else {
ll = prevMinL;
newMin = no;
}
hh = prevMaxH;
newMax = no;
}
}
def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(h), 0, barNumber));
def newState = GetValue(state, 0) != GetValue(state, 1);
def offset = barCount - barNumber + 1;
def highPoint = state == state.overbought and h == hh and isOverBought;
def lowPoint = state == state.oversold and l == ll and isOversold;
def lastH;
if highPoint and offset > 1 {
lastH = fold iH = 1 to offset with tH = h
while !IsNaN(tH) and !GetValue(newState, -iH) do
if GetValue(newMax, -iH) or iH == offset - 1 and GetValue(h, -iH) == tH then na else tH;
} else {
lastH = na;
}
def lastL;
if lowPoint and offset > 1 {
lastL = fold iL = 1 to offset with tL = l
while !IsNaN(tL) and !GetValue(newState, -iL) do
if GetValue(newMin, -iL) or iL == offset - 1 and GetValue(l, -iL) == tL then na else tL;
} else {
lastL = na;
}
def ZZ;
if barNumber == 1 {
ZZ = fold iF = 1 to offset with tP = na while IsNaN(tP) do
if GetValue(state, -iF) == GetValue(state.overbought, 0) then l else
if GetValue(state, -iF) == GetValue(state.oversold, 0) then h else na;
} else if barNumber == barCount {
ZZ = if highPoint or state == state.oversold and l > ll and isOversold then h else
if lowPoint or state == state.overbought and h < hh and isOverBought then l else na;
} else {
ZZ = if !IsNaN(lastH) then lastH else if !IsNaN(lastL) then lastL else na;
}
#ZZ.SetDefaultColor(GetColor(1));
def ZZHi;
if barNumber == 1 {
ZZHi = fold i = 1 to offset with P = na while IsNaN(P) do
if GetValue(state, -i) == GetValue(state.oversold, 0) then h else na;
} else if barNumber == barCount {
ZZHi = if highPoint or state == state.oversold and l > ll and isOversold then h else na;
} else {
ZZHi = if !IsNaN(lastH) then lastH else na;
}
def ZZLo;
if barNumber == 1 {
ZZLo = fold j = 1 to offset with t = na while IsNaN(t) do
if GetValue(state, -j) == GetValue(state.overbought, 0) then l else na;
} else if barNumber == barCount {
ZZLo = if lowPoint or state == state.overbought and h < hh and isOverBought then l else na;
} else {
ZZLo = if !IsNaN(lastL) then lastL else na;
}
plot ZZLine = ZZ;
ZZLine.EnableApproximation();
ZZLine.SetHiding(!ShowZigZag);
ZZLine.SetDefaultColor(Color.WHITE);
def ph = if !isNaN(ZZHi) then h else na;
def pl = if !isNaN(ZZLo) then l else na;
# extend the current valley line to the right edge of the chart
def counbot = if IsNaN(ZZLo) and !IsNaN(ZZLo[1]) then 1 else counbot[1] + 1;
def bottom = GetValue(zz, counbot);
plot bottomLine = if isNaN(close) then na else bottom[-3];
bottomLine.SetPaintingStrategy(PaintingStrategy.DASHES);
bottomLine.SetDefaultColor(GlobalColor("Up"));
bottomLine.SetHiding(!HorizontalLines);
# extend the current valley line to the right edge of the chart
def counpek = if IsNaN(ZZHi) and !IsNaN(ZZHi[1]) then 1 else counpek[1] + 1;
def peak = GetValue(zz, counpek);
plot peakLine = if isNaN(close) then na else peak[-3];
peakLine.SetPaintingStrategy(PaintingStrategy.DASHES);
peakLine.SetDefaultColor(GlobalColor("down"));
peakLine.SetHiding(!HorizontalLines);
def PrevHibar = barssince(!isNaN(zzHi[1]));
def PrevLobar = barssince(!isNaN(zzLo[1]));
def HH_ = h > GetValue(h,PrevHibar);
def LL_ = l < GetValue(l,PrevLobar);
AddChartBubble(showBubbles and ph and HH_, high, "HH", Color.RED, yes);
AddChartBubble(showBubbles and ph and !HH_, high, "LH", Color.DARK_RED, yes);
AddChartBubble(showBubbles and pl and LL_, low, "LL", Color.GREEN, no);
AddChartBubble(showBubbles and pl and !LL_, low, "HL", Color.DARK_GREEN, no);
#### END