Author Message:
The N Bar Reversal Detector is designed to detect and highlight N-bar reversal patterns in user charts, where N represents the length of the candle sequence used to detect the patterns. The script incorporates various trend indicators to filter out detected signals and offers a range of customizable settings to fit different trading strategies.
CODE:
CSS:
#/ Indicator For TOS
#// © LuxAlgo
# indicator("N Bar Reversal Detector [LuxAlgo]", 'LuxAlgo - N Bar Reversal Detector',
# Converted by Sam4Cok@Samer800 - 10/2024
input showSignals = yes;
input PatternType = {"Normal", "Enhanced", default "All"}; # "Pattern Type"
input ReversalPatternSequenceLength = 7; # 'Reversal Pattern Sequence Length'
input MinPercentageOfRequiredCandles = 50; # 'Min Percentage of Required Candles'
input DerivedSupportAndResistance = {default "Level", "None"}; # "Derived Support and Resistance"
input trendType = {"Moving Average Cloud", "Supertrend", "Donchian Channels", default "None"}; # "Filtering"
input FilteringType = {default "Aligned", "Opposite"};
input movAvgType = AverageType.HULL;
input fastLength = 50; # 'Fast Length'
input slowLength = 200; # 'Slow Length'
input atrLength = 10; # 'ATR Length'
input supertrendFactor = 3.0; # 'Factor'
input DonchianChannelLength = 13; # 'Length'
def na = Double.NaN;
def last = isNaN(close);
def minBars = Max(Min(MinPercentageOfRequiredCandles / 100, 1), 0);
def numBars = Max(ReversalPatternSequenceLength, 2);
def none = DerivedSupportAndResistance==DerivedSupportAndResistance."None";
def filterUp; def filterDn;
Switch (PatternType) {
Case "Normal" :
filterUp = close < high[numBars];
filterDn = close > low[numBars];
Case "Enhanced" :
filterUp = close > high[numBars];
filterDn = close < low[numBars];
Default :
filterUp = yes;
filterDn = yes;
}
Script supertrend {
input factor = 3;
input atrPeriod = 10;
def src = hl2;
def tr = if isNaN(high[1]) then high - low else TrueRange(high, close, low);
def atr = WildersAverage(tr, atrPeriod);
def upBand = src + factor * atr;
def loBand = src - factor * atr;
def lowerBand; def upperBand;
def prevLowerBand = if isNaN(lowerBand[1]) then prevLowerBand[1] else lowerBand[1];
def prevUpperBand = if isNaN(upperBand[1]) then prevUpperBand[1] else upperBand[1];
lowerBand = if loBand > prevLowerBand or close[1] < prevLowerBand then loBand else prevLowerBand;
upperBand = if upBand < prevUpperBand or close[1] > prevUpperBand then upBand else prevUpperBand;
def _direction;
def superTrend;
def prevSuperTrend = superTrend[1];
if isNaN(atr[1]) {
_direction = 1;
} else if prevSuperTrend == prevUpperBand {
_direction = if close > upperBand then -1 else 1;
} else {
_direction = if close < lowerBand then 1 else -1;
}
superTrend = if _direction == -1 then lowerBand else upperBand;
plot st = if isNaN(superTrend) then Double.NaN else superTrend;
plot dir = if isNaN(_direction) then Double.NaN else _direction;
}
# isBullishReversal {
def isBullLow = fold i = 1 to numBars with p=low[numBars] while high[i] <= high[numBars] do
Min(p, low[i]);
def bearCount = fold i1 = 1 to numBars with p1 while high[i1] <= high[numBars] do
if open[i1] > close[i1] then p1 + 1 else p1 ;
def bullReversal1 = bearCount / (numBars - 1) >= (minBars);
def bullReversal = if isNaN(bullReversal1) then no else bullReversal1;
def bullLow = Min(isBullLow, low);
def isBullish = bullReversal and high > high[numBars];
#isBearishReversal() =>
def isBearHigh = fold j = 1 to numBars with q=high[numBars] while low[j] >= low[numBars] do
Max(q, high[j]);
def bullCount = fold j1 = 1 to numBars with q1 while low[j1] >= low[numBars] do
if open[j1] < close[j1] then q1 + 1 else q1 ;
def bearReversal = bullCount / (numBars -1) >= (minBars);
#def bearReversal = if isNaN(bearReversal1) then no else bearReversal1;
def bearHigh = Max(isBearHigh, high);
def isBearish = bearReversal and low < low[numBars];
#// Calculations - Trend Indicators - Moving Average Cloud
def maFast = movingAverage(movAvgType, close, fastLength);
def maSlow = movingAverage(movAvgType, close, slowLength);
def maColor = maFast > maSlow; # ? trendAC : trendSC
#// Calculations - Trend Indicators - Supertrend
def supertrend = supertrend(supertrendFactor, atrLength).st;
def direction = supertrend(supertrendFactor, atrLength).dir;
def bodyMid = (open + close) / 2 ;
#// Calculations - Trend Indicators - Donchian Channels
def upp = highest(close, DonchianChannelLength);
def loo = lowest(close, DonchianChannelLength);
def os = if upp > upp[1] then 1 else
if loo < loo[1] then 0 else os[1];
#// Calculations - 3-Bar Reversal Pattern
def align = FilteringType == FilteringType."Aligned";
def oppo = FilteringType == FilteringType."Opposite";
def mAvg = trendType == trendType."Moving Average Cloud";
def C_DnTrend; # = true
def C_UpTrend; # = true
def upper;
def lower;
Switch (trendType) {
Case "Moving Average Cloud" :
upper = maFast;
lower = maSlow;
if Align {
C_DnTrend = close < maFast and maFast < maSlow;
C_UpTrend = close > maFast and maFast > maSlow;
} else if Oppo {
C_DnTrend = close > maFast and maFast > maSlow;
C_UpTrend = close < maFast and maFast < maSlow;
} else {
C_DnTrend = yes;
C_UpTrend = yes;
}
Case "Supertrend" :
upper = if direction < 0 then supertrend else na;
lower = if direction < 0 then na else supertrend;
if Align {
C_DnTrend = direction > 0;
C_UpTrend = direction < 0;
} else if Oppo {
C_DnTrend = direction < 0;
C_UpTrend = direction > 0;
} else {
C_DnTrend = yes;
C_UpTrend = yes;
}
Case "Donchian Channels" :
lower = if os == 0 then upp else if os[-1] == 0 then upp[-1] else na;
upper = if os == 1 then loo else if os[-1] == 1 then loo[-1] else na;
if Align {
C_DnTrend = os == 0;
C_UpTrend = os == 1;
} else if Oppo {
C_DnTrend = os == 1;
C_UpTrend = os == 0;
} else {
C_DnTrend = yes;
C_UpTrend = yes;
}
Default :
upper = na;
lower = na;
C_DnTrend = yes;
C_UpTrend = yes;
}
def upTrend = if upper then upper else na;
def dnTrend = if lower then lower else na;
AddCloud(if mAvg then na else bodyMid, upTrend, Color.DARK_GREEN, Color.DARK_GREEN, yes);
AddCloud(if mAvg then na else dnTrend, bodyMid, Color.DARK_RED, Color.DARK_RED, yes);
AddCloud(if mAvg then upTrend else na, dnTrend, Color.DARK_GREEN, Color.DARK_RED, yes);
#-- lines
def bullishReversal = isBullish and C_UpTrend;
def bearishReversal = isBearish and C_DnTrend;
def condUp = bullishReversal and !bullishReversal[1] and filterUp;
def condDn = bearishReversal and !bearishReversal[1] and filterDn;
def cntUp = if condUp[-numBars] then 0 else cntUp[1] + 1;
def cntDn = if condDn[-numBars] then 0 else cntDn[1] + 1;
def lnAT; def lnAB; def bullProcess; def bullProcess2; def bullProcess1;
def bxA; def bxA1; def lbAT;
if condUp[-numBars] {
lbAT = 2;
bullProcess = yes;
lnAT = high;
lnAB = bullLow[-numBars];
bxA = bxA1[1];
bullProcess2 = bullProcess1[1];
} else if bullProcess[1] and cntUp>=numBars-1 {
if (close[1] > lnAT[1]) {
lbAT = if bullProcess[1] and bullProcess[1] != bullProcess[2] then 0 else 1;
bullProcess = no;
bxA = lnAB[1];
bullProcess2 = yes;
} else if (close[1] < lnAB[1]) or bearishReversal { #
lbAT = 0;
bullProcess = no;
bxA = bxA1[1];
bullProcess2 = bullProcess1[1];
} else {
lbAT = 0;
bullProcess = bullProcess[1];
bxA = bxA1[1];
bullProcess2 = bullProcess1[1];
}
lnAT = if !bullProcess then na else lnAT[1];
lnAB = if !bullProcess then na else lnAB[1];
} else {
bullProcess = bullProcess[1];
bxA = bxA1[1];
bullProcess2 = bullProcess1[1];
lbAT = 0;
lnAT = if !bullProcess then na else lnAT[1];
lnAB = if !bullProcess then na else lnAB[1];
}
if (bullProcess2 and !none) {
if close > bxA {
bxA1 = bxA;
bullProcess1 = bullProcess2;
} else {
bxA1 = bxA;
bullProcess1 = no;}
} else {
bxA1 = na;
bullProcess1 = bullProcess2;
}
def lnSB; def lnST; def bearProcess; def bearProcess2; def bearProcess1;
def bxS; def bxS1; def lbST;
if condDn[-numBars] {
lbST = 2;
bearProcess = yes;
lnSB = low;
lnST = bearHigh[-numBars];
bxS = bxS1[1];
bearProcess2 = bearProcess1[1];
} else if bearProcess[1] and cntDn>=numBars-1 {
if (close[1] > lnST[1]) or bullishReversal {
lbST = 0;
bearProcess = no;
bxS = bxS1[1];
bearProcess2 = bearProcess1[1];
} else if (close[1] < lnSB[1]) {
lbST = if bearProcess[1] and bearProcess[1] != bearProcess[2] then 0 else 1;
bearProcess = no;
bxS = lnST[1];
bearProcess2 = yes;
} else {
lbST = 0;
bearProcess = bearProcess[1];
bxS = bxS1[1];
bearProcess2 = bearProcess1[1];
}
lnSB = if !bearProcess then na else lnSB[1];
lnST = if !bearProcess then na else lnST[1];
} else {
bearProcess = bearProcess[1];
bxS = bxS1[1];
bearProcess2 = bearProcess1[1];
lbST = 0;
lnSB = if !bearProcess then na else lnSB[1];
lnST = if !bearProcess then na else lnST[1];
}
if (bearProcess2 and !none) {
if close < bxS {
bxS1 = bxS;
bearProcess1 = bearProcess2;
} else {
bxS1 = bxS;
bearProcess1 = no;}
} else {
bxS1 = na;
bearProcess1 = bearProcess2;
}
def cloudUp1 = if isNaN(cntUp) then cloudUp1[1] + 1 else cntUp;
def cloudDn1 = if isNaN(cntDn) then cloudDn1[1] + 1 else cntDn;
def cloudUp = cloudUp1;
def cloudDn = cloudDn1;
plot bgBullTop = if !last and cloudUp <= numBars and lnAT then lnAT else na;
plot bgBullBot = if !last and cloudUp <= numBars and lnAB then lnAB else na;
plot bgBullTop1 = if !last and cloudUp >= numBars and lnAT==lnAT[1] then lnAT else na;
plot bgBullBot1 = if !last and cloudUp >= numBars and lnAB==lnAB[1] then lnAB else na;
plot bgBearTop = if !last and cloudDn <= numBars and lnST then lnST else na;
plot bgBearBot = if !last and cloudDn <= numBars and lnSB then lnSB else na;
plot bgBearTop1 = if !last and cloudDn >= numBars and lnST==lnST[1] then lnST else na;
plot bgBearBot1 = if !last and cloudDn >= numBars and lnSB==lnSB[1] then lnSB else na;
bgBullTop.SetDefaultColor(Color.GREEN);
bgBullBot.SetDefaultColor(Color.GREEN);
bgBullTop1.SetDefaultColor(Color.DARK_GREEN);
bgBullBot1.SetDefaultColor(Color.DARK_GREEN);
bgBearTop.SetDefaultColor(Color.RED);
bgBearBot.SetDefaultColor(Color.RED);
bgBearTop1.SetDefaultColor(Color.DARK_RED);
bgBearBot1.SetDefaultColor(Color.DARK_RED);
plot sigUp = if showSignals and lbAT[numBars]==2 then low else na;
plot sigDn = if showSignals and lbST[numBars]==2 then high else na;
plot ptUp = if showSignals and lbAT[-1]==1 and lbAT[numBars]!=2 then low - ATR(5)/5 else na;
plot ptDn = if showSignals and lbST[-1]==1 and lbST[numBars]!=2 then high + ATR(5)/5 else na;
sigUp.SetDefaultColor(Color.CYAN);
sigDn.SetDefaultColor(Color.MAGENTA);
sigUp.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
sigDn.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
ptUp.SetDefaultColor(Color.CYAN);
ptUp.SetPaintingStrategy(PaintingStrategy.SQUARES);
ptDn.SetDefaultColor(Color.MAGENTA);
ptDn.SetPaintingStrategy(PaintingStrategy.SQUARES);
plot lvlUp = if !last and bxA1 then bxA1 else na;
plot lvlDn = if !last and bxS1 then bxS1 else na;
lvlUp.SetDefaultColor(Color.DARK_GREEN);
lvlUp.SetPaintingStrategy(PaintingStrategy.DASHES);
lvlDn.SetDefaultColor(Color.DARK_RED);
lvlDn.SetPaintingStrategy(PaintingStrategy.DASHES);
AddCloud(if cloudUp <= numBars then bgBullTop else na, bgBullBot, Color.DARK_GREEN);
AddCloud(if cloudDn <= numBars then bgBearTop else na, bgBearBot, Color.DARK_RED);
#-- end of code