ABCD Pattern screener
Based on a request in the italian support forum, it scans for both Bullish and Bearish ABCD patterns.
https://www.prorealcode.com/topic/fibonacci-2/page/4/#post-108394
https://www.forex.com/en-uk/education/education-themes/technical-analysis/abcd-pattern/
//------------------------------------------------------------------------------------
// Bullish pattern
//------------------------------------------------------------------------------------
IF BarIndex = 0 THEN
LmaxBars = 100
LminBars = 5
//Ldistance = 15 * pipsize
LpointA = high
LbarA = BarIndex
LpointB = low
LbarB = BarIndex
LpointC = 0
LbarC = 0
LpointD = 0
//LbarD = 0
Lcount = 0
//XLpointA = 0
//XLbarA = 0
//XLpointB = 0
//XLbarB = 0
//XLpointC = 0
//XLbarC = 0
//XLpointD = 0
//XLbarD = 0
ENDIF
//
IF Lcount > LmaxBars THEN
//XLpointA = LpointA
//XLbarA = LbarA
//XLpointB = LpointB
//XLbarB = LbarB
//XLpointC = LpointC
//XLbarC = LbarC
//XLpointD = LpointD
//XLbarD = LbarD
LpointA = high
LbarA = BarIndex
LpointB = low
LbarB = BarIndex
LpointC = 0
LbarC = 0
LpointD = 0
//LbarD = 0
Lcount = 0
ENDIF
Lcount = Lcount + 1 //incrementare il passare delle Bars per azzerare tutto quando arriva a 100
//
// Determinare se il prezzo scende sotto A, in tal caso avremo una nuova A più bassa e ripartiremo daccapo con B,C e D
LpointA = max(LpointA,high)
IF LpointA > LpointA[1] THEN
LbarA = BarIndex
Lcount = 0
LpointB = low
LbarB = BarIndex
LpointC = 0
LbarC = 0
LpointD = 0
//LbarD = 0
ENDIF
//
// Determinare se il prezzo sale sopra B, in tal caso avremo una nuova B più alta e ripartiremo daccapo con C e D
IF LpointC = 0 THEN
LpointB = min(LpointB,low)
IF LpointB < LpointB[1] THEN
LbarB = BarIndex
ENDIF
ENDIF
// Calcolare la differenza tra i punti A e B e le due percentuali di fibonacci da usare per la verifica di C
LdiffAB = LpointA - LpointB
LfibC1 = LdiffAB * 0.618
LfibC2 = LdiffAB * 0.786
LfibD1 = LpointC - (LfibC1 * 1.270)
LfibD2 = LpointC - (LfibC2 * 1.618)
IF high >= (LpointB + LfibC1) AND high <= (LpointB + LfibC2) THEN
// se il MINIMO è tra 0.618 e 0.786 abbiamo trovato il Lpoint C....
LpointC = high
LbarC = BarIndex
IF LpointC < LpointC[1] THEN
LpointC = LpointC[1]
LbarC = LbarC[1]
ENDIF
ELSIF close > (LpointB + LfibC2) THEN
// ...altrimenti si riparte daccapo con un nuovo Lpoint A ed un nuovo Lpoint B
LpointA = high
LbarA = BarIndex
LpointB = low
LbarB = BarIndex
LpointC = 0
LbarC = 0
//LbarD = 0
LpointD = 0
Lcount = 0
ENDIF
//
// Una volta superato il 161.8 si riparte daccapo
//
IF close < LfibD2 AND LpointD > 0 THEN
//XLpointA= LpointA
//XLbarA = LbarA
//XLpointB= LpointB
//XLbarB = LbarB
//XLpointC= LpointC
//XLbarC = LbarC
//XLpointD= LpointD
//XLbarD = LbarD
LpointA = high
LbarA = BarIndex
LpointB = low
LbarB = BarIndex
LpointC = 0
LbarC = 0
LpointD = 0
//LbarD = 0
Lcount = 0
ENDIF
IF LpointC > 0 THEN
IF LpointD = 0 THEN
IF close <= LfibD1 AND close >= LfibD2 THEN
LpointD = close
//LbarD = BarIndex
ELSIF close < LfibD2 THEN
LpointD = LfibD2
//LbarD = BarIndex
ENDIF
ELSE
IF close <= LfibD1 AND close >= LfibD2 THEN
LpointD = close
IF LpointD < LpointD[1] THEN
//LbarD = BarIndex
ELSE
LpointD = LpointD[1]
ENDIF
ELSE
//XLpointA= LpointA
//XLbarA = LbarA
//XLpointB= LpointB
//XLbarB = LbarB
//XLpointC= LpointC
//XLbarC = LbarC
//XLpointD= LpointD
//XLbarD = LbarD
LpointA = high
LbarA = BarIndex
Lcount = 0
LpointB = 0
LbarB = 0
LpointC = 0
LbarC = 0
LpointD = 0
//LbarD = 0
ENDIF
ENDIF
ENDIF
// si stampano i punti trovati, ognuno dipendente dal precedente, si stampa A, poi B solo se A è stato stampato, poi C solo se B è stato stampato ed infine D se anche C è stato stampato
IF LpointC > 0 THEN
IF ((LbarC - LbarA) < LminBars ) THEN
LpointC = 0
x = BarIndex - LbarB
FOR i = x DOWNTO 0
IF low[i] < LpointB THEN
LpointB = low[i]
LbarB = BarIndex[i]
ENDIF
NEXT
ENDIF
ENDIF
//IF LpointD > 0 THEN
//IF ((LbarC - LbarA) < LminBars ) OR ((LbarD - LbarC) < LminBars ) THEN
//LpointD = 0
//ENDIF
//ENDIF
IF LpointA > 0 THEN
IF LpointB > 0 THEN
IF LpointC > 0 THEN
IF LpointD > 0 THEN
//IF LpointD[1] = 0 THEN
//XLpointA = LpointA
//XLbarA = LbarA
//XLpointB = LpointB
//XLbarB = LbarB
//XLpointC = LpointC
//XLbarC = LbarC
//XLpointD = LpointD
//XLbarD = LbarD
//ENDIF
//DRAWTEXT("A",LbarA,LpointA - Ldistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("B",LbarB,LpointB + Ldistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("C",LbarC,LpointC - Ldistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("D",LbarD,LpointD + Ldistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTRIANGLE(LbarA,LpointA,LbarB,LpointB,LbarC,LpointC)coloured(50,205,50,255)
//DRAWTRIANGLE(LbarC,LpointC,LbarD,LpointC,LbarD,LpointD)coloured(50,205,50,255)
ENDIF
ENDIF
ENDIF
ENDIF
//IF LpointD = 0 AND XLpointD > 0 THEN
//DRAWTEXT("A",XLbarA,XLpointA - Ldistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("B",XLbarB,XLpointB + Ldistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("C",XLbarC,XLpointC - Ldistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("D",XLbarD,XLpointD + Ldistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTRIANGLE(XLbarA,XLpointA,XLbarB,XLpointB,XLbarC,XLpointC)coloured(50,205,50,255)
//DRAWTRIANGLE(XLbarC,XLpointC,XLbarD,XLpointC,XLbarD,XLpointD)coloured(50,205,50,255)
//ENDIF
//------------------------------------------------------------------------------------
// Bearish pattern
//------------------------------------------------------------------------------------
IF BarIndex = 0 THEN
SmaxBars = 100
SminBars = 5
//Sdistance = 10 * pipsize
SpointA = low
SbarA = BarIndex
SpointB = high
SbarB = BarIndex
SpointC = 0
SbarC = 0
SpointD = 0
SbarD = 0
Scount = 0
//XSpointA = low
//XSbarA = BarIndex
//XSpointB = high
//XSbarB = BarIndex
//XSpointC = 0
//XSbarC = 0
//XSpointD = 0
//XSbarD = 0
ENDIF
//
IF Scount > SmaxBars THEN
//XSpointA = SpointA
//XSbarA = SbarA
//XSpointB = SpointB
//XSbarB = SbarB
//XSpointC = SpointC
//XSbarC = SbarC
//XSpointD = SpointD
//XSbarD = SbarD
SpointA = low
SbarA = BarIndex
SpointB = high
SbarB = BarIndex
SpointC = 0
SbarC = 0
SpointD = 0
SbarD = 0
Scount = 0
ENDIF
Scount = Scount + 1 //incrementare il passare delle Bars per azzerare tutto quando arriva a 100
//
// Determinare se il prezzo scende sotto A, in tal caso avremo una nuova A più bassa e ripartiremo daccapo con B,C e D
SpointA = min(SpointA,low)
IF SpointA < SpointA[1] THEN
SbarA = BarIndex
Scount = 0
SpointB = high
SbarB = BarIndex
SpointC = 0
SbarC = 0
SpointD = 0
SbarD = 0
ENDIF
//
// Determinare se il prezzo sale sopra B, in tal caso avremo una nuova B più alta e ripartiremo daccapo con C e D
IF SpointC = 0 THEN
SpointB = max(SpointB,high)
IF SpointB > SpointB[1] THEN
SbarB = BarIndex
ENDIF
ENDIF
// Calcolare la differenza tra i punti A e B e le due percentuali di fibonacci da usare per la verifica di C
SdiffAB = SpointB - SpointA
SfibC1 = SdiffAB * 0.618
SfibC2 = SdiffAB * 0.786
SfibD1 = SpointC + (SfibC1 * 1.270)
SfibD2 = SpointC + (SfibC2 * 1.618)
IF low <= (SpointB - SfibC1) AND low >= (SpointB - SfibC2) THEN
// se il MINIMO è tra 0.618 e 0.786 abbiamo trovato il Spoint C....
SpointC = low
SbarC = BarIndex
IF SpointC < SpointC[1] THEN
SpointC = SpointC[1]
SbarC = SbarC[1]
ENDIF
ELSIF close < (SpointB - SfibC2) THEN
// ...altrimenti si riparte daccapo con un nuovo Spoint A ed un nuovo Spoint B
SpointA = low
SbarA = BarIndex
SpointB = high
SbarB = BarIndex
SpointC = 0
SbarC = 0
SbarD = 0
SpointD = 0
Scount = 0
ELSIF close > SpointB THEN
//SpointB = high
//SbarB = BarIndex
//SpointC = 0
//SbarC = 0
//SbarD = 0
//SpointD = 0
ENDIF
//
// Una volta superato il 161.8 si riparte daccapo
//
IF close > SfibD2 AND SpointD > 0 THEN
//XSpointA= SpointA
//XSbarA = SbarA
//XSpointB= SpointB
//XSbarB = SbarB
//XSpointC= SpointC
//XSbarC = SbarC
//XSpointD= SpointD
//XSbarD = SbarD
SpointA = low
SpointA = low
SbarA = BarIndex
SpointB = high
SbarB = BarIndex
SpointC = 0
SbarC = 0
SpointD = 0
SbarD = 0
Scount = 0
ENDIF
IF SpointC > 0 THEN
IF SpointD = 0 THEN
IF close >= SfibD1 AND close <= SfibD2 THEN
SpointD = close
SbarD = BarIndex
ELSIF close > SfibD2 THEN
SpointD = SfibD2
SbarD = BarIndex
ENDIF
ELSE
IF close >= SfibD1 AND close <= SfibD2 THEN
SpointD = close
IF SpointD > SpointD[1] THEN
SbarD = BarIndex
ELSE
SpointD = SpointD[1]
ENDIF
ELSE
//XSpointA= SpointA
//XSbarA = SbarA
//XSpointB= SpointB
//XSbarB = SbarB
//XSpointC= SpointC
//XSbarC = SbarC
//XSpointD= SpointD
//XSbarD = SbarD
SpointA = low
SbarA = BarIndex
Scount = 0
SpointB = 0
SbarB = 0
SpointC = 0
SbarC = 0
SpointD = 0
SbarD = 0
ENDIF
ENDIF
ENDIF
// si stampano i punti trovati, ognuno dipendente dal precedente, si stampa A, poi B solo se A è stato stampato, poi C solo se B è stato stampato ed infine D se anche C è stato stampato
IF SpointC > 0 THEN
IF ((SbarC - SbarA) < SminBars ) THEN
SpointC = 0
x = BarIndex - SbarB
FOR i = x DOWNTO 0
IF high[i] > SpointB THEN
SpointB = high[i]
SbarB = BarIndex[i]
ENDIF
NEXT
ENDIF
ENDIF
IF SpointD > 0 THEN
IF ((SbarD - SbarC) < SminBars ) THEN
//IF SpointD > 0 THEN
//IF ((SbarC - SbarA) < SminBars ) OR ((SbarD - SbarC) < SminBars ) THEN
//SpointD = 0
//ENDIF
//ENDIF
SpointD = 0
SbarD = 0
ENDIF
ENDIF
IF SpointA > 0 THEN
IF SpointB > 0 THEN
IF SpointC > 0 THEN
IF SpointD > 0 THEN
//XSpointA = SpointA
//XSbarA = SbarA
//XSpointB = SpointB
//XSbarB = SbarB
//XSpointC = SpointC
//XSbarC = SbarC
//XSpointD = SpointD
//XSbarD = SbarD
//DRAWTEXT("A",SbarA,SpointA - Sdistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("B",SbarB,SpointB + Sdistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("C",SbarC,SpointC - Sdistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("D",SbarD,SpointD + Sdistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTRIANGLE(SbarA,SpointA,SbarB,SpointB,SbarC,SpointC)coloured(200,120,120,255)
//DRAWTRIANGLE(SbarC,SpointC,SbarD,SpointC,SbarD,SpointD)coloured(200,120,120,255)
ENDIF
ENDIF
ENDIF
ENDIF
//IF SpointD = 0 AND XSpointD > 0 THEN
//DRAWTEXT("A",XSbarA,XSpointA - Sdistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("B",XSbarB,XSpointB + Sdistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("C",XSbarC,XSpointC - Sdistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTEXT("D",XSbarD,XSpointD + Sdistance,Dialog,Bold,14) coloured(205,0,205,255)
//DRAWTRIANGLE(XSbarA,XSpointA,XSbarB,XSpointB,XSbarC,XSpointC)coloured(200,120,120,255)
//DRAWTRIANGLE(XSbarC,XSpointC,XSbarD,XSpointC,XSbarD,XSpointD)coloured(200,120,120,255)
//ENDIF
x = 0
IF LpointD > 0 THEN
x = 1
ELSIF SpointD > 0 THEN
x = 2
ENDIF
SCREENER[x](x AS "1=↑, 2=↓")