Harmonic Patterns

this thread on Harmonic patterns was closed. I will open a new one. I have rewritten the code so that changes in the algorithm that defines the pattern can more easily be implemented. I have the books on these patterns but admit I just read only some of the pages. So the patterns are probably not defined 100% correctly but here is a start. Maybe there are some people out there who can point to errors. With these Fib numbers I just took the range. So if the retrace is showing either 0.382 or 0.886 I just use the entire range. Because he is taling about all the other Fibonacci numbers that are in between and that covers about the entire range :smile:

And it is easy to add more patterns. I added a couple but they have more. Code below

so I made some money on the bullish ABCD at the open.

This is the situation now:

_SECTION_BEGIN( "Harmonic patterns" );
/*
ratio labels
AB_AX means the ratio (A-B)/(A-X). It is the retracement of A to B over the price range A to X
BC_AB means the ratio (C-B)/(A-B)
CD_BC means the ratio (C-D)/(C-B)
AD_AX means the ratio (A-D)/(A-X)
*/

GfxSetZOrder( -5 );
GfxSetCoordsMode( 1 );

bi = BarIndex();
fvb = FirstVisibleValue( Ref( bi, -0 ) );
lvb = LastVisibleValue( Ref( bi, -1 ) );

// PARAMETERS
rightstrength = Param( "Right Strength", 10, 2, 50, 1 );
leftstrength = Param( "Left Strength", 10, 2, 50, 1 );
bu = ParamToggle( "Bullish Pattern", "Off|On", 1 );
be = ParamToggle( "Bearish Pattern", "Off|On", 1 );
showABCD = ParamToggle( "Show ABCD", "Off|On", 1 );
showGartley = ParamToggle( "Show Gartley", "Off|On", 0 );
showBat = ParamToggle( "Show Bat", "Off|On", 0 );
showAlternateBat = ParamToggle( "Show Alternate Bat", "Off|On", 0 );
showButterfly = ParamToggle( "Show Butterfly", "Off|On", 0 );
showCrab = ParamToggle( "Show Crab", "Off|On", 0 );
showDeepCrab = ParamToggle( "Show Deep Crab", "Off|On", 0 );
showCypher = ParamToggle( "Show Cypher", "Off|On", 0 );
ft = ParamList( "Font Type", "Tahoma|Arial Black|Verdana|Courier New|Times New Roman|Open Sans|Segoe UI|DejaVu Sans", 6 );
sz = Param( "Font Size", 20, 8, 50, 1 );
st = Param( "Separation of Letters", 3, 1, 10, 1 );
dl = Param( "Dashed Line Number", 2, 1, 4, 1 );
showDotsAtD = ParamToggle( "Show Dots at D", "Off|On", 1 );
plotFractals = ParamToggle( "Plot Fractal Pivot Points", "Off|On", 1 );
ps = ParamToggle( "Swing D constraint", "use only AD_AX contraint|use both AD_AX AND CB_BC constraint", 1 );
deviation = Param( "Deviation", 10, 0.1, 100, 0.1 );

// Gartley
Gartley_MinXB = 0.618 - 0.618 * deviation / 100; // retrace from A to B over distance X to A
Gartley_MaxXB = 0.618 + 0.618 * deviation / 100;
Gartley_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Gartley_MaxAC = 0.886 + 0.886 * deviation / 100;
Gartley_MinBD = 1.13 - 1.13 * deviation / 100; // retrace from C to D over distance B to C
Gartley_MaxBD = 1.618 + 1.618 * deviation / 100;
Gartley_MinXD = 0.786 - 0.786 * deviation / 100; // retrace from A to D over distance X to A
Gartley_MaxXD = 0.786 + 0.786 * deviation / 100;

// Bat
Bat_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Bat_MaxXB = 0.5 + 0.5 * deviation / 100;
Bat_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Bat_MaxAC = 0.886 + 0.886 * deviation / 100;
Bat_MinBD = 1.618 - 1.618 * deviation / 100; // retrace from C to D over distance B to C
Bat_MaxBD = 2.618 + 2.618 * deviation / 100;
Bat_MinXD = 0.886 - 0.886 * deviation / 100; // retrace from A to D over distance X to A
Bat_MaxXD = 0.886 + 0.886 * deviation / 100;

// Alternate Bat
AlternateBat_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
AlternateBat_MaxXB = 0.382 + 0.382 * deviation / 100;
AlternateBat_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
AlternateBat_MaxAC = 0.886 + 0.886 * deviation / 100;
AlternateBat_MinBD = 2.0 - 2.0 * deviation / 100; // retrace from C to D over distance B to C
AlternateBat_MaxBD = 3.618 + 3.618 * deviation / 100;
AlternateBat_MinXD = 1.13 - 1.13 * deviation / 100; // retrace from A to D over distance X to A
AlternateBat_MaxXD = 1.13 + 1.13 * deviation / 100;

// Butterfly
Butterfly_MinXB = 0.786 - 0.786 * deviation / 100; // retrace from A to B over distance X to A
Butterfly_MaxXB = 0.786 + 0.786 * deviation / 100;
Butterfly_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Butterfly_MaxAC = 0.886 + 0.886 * deviation / 100;
Butterfly_MinBD = 1.618 - 1.618 * deviation / 100; // retrace from C to D over distance B to C
Butterfly_MaxBD = 2.24 + 2.24 * deviation / 100;
Butterfly_MinXD = 1.27 - 1.27 * deviation / 100; // retrace from A to D over distance X to A
Butterfly_MaxXD = 1.27 + 1.27 * deviation / 100;

// Crab
Crab_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Crab_MaxXB = 0.618 + 0.618 * deviation / 100;
Crab_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Crab_MaxAC = 0.886 + 0.886 * deviation / 100;
Crab_MinBD = 2.618 - 2.618 * deviation / 100; // retrace from C to D over distance B to C
Crab_MaxBD = 3.618 + 3.618 * deviation / 100;
Crab_MinXD = 1.618 - 1.618 * deviation / 100; // retrace from A to D over distance X to A
Crab_MaxXD = 1.618 + 1.618 * deviation / 100;

// Deep Crab
DeepCrab_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
DeepCrab_MaxXB = 0.618 + 0.618 * deviation / 100;
DeepCrab_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
DeepCrab_MaxAC = 0.886 + 0.886 * deviation / 100;
DeepCrab_MinBD = 2.618 - 2.618 * deviation / 100; // retrace from C to D over distance B to C
DeepCrab_MaxBD = 3.618 + 3.618 * deviation / 100;
DeepCrab_MinXD = 1.618 - 1.618 * deviation / 100; // retrace from A to D over distance X to A
DeepCrab_MaxXD = 1.618 + 1.618 * deviation / 100;

// Cypher
Cypher_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Cypher_MaxXB = 0.618 + 0.618 * deviation / 100;
Cypher_MinAC = 1.13 - 1.13 * deviation / 100; // retrace from B to C over distance A to B
Cypher_MaxAC = 1.414 + 1.414 * deviation / 100;
Cypher_MinBD = 1.272 - 1.272 * deviation / 100; // retrace from C to D over distance B to C
Cypher_MaxBD = 2.0 + 2.0 * deviation / 100;
Cypher_MinXD = 0.786 - 0.786 * deviation / 100; // retrace from A to D over distance X to A
Cypher_MaxXD = 0.786 + 0.786 * deviation / 100;

ABCD_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
ABCD_MaxAC = 0.886 + 0.886 * deviation / 100;
ABCD_MinBD = 1.13 - 1.13 * deviation / 100; // retrace from C to D over distance B to C
ABCD_MaxBD = 2.618 + 2.618 * deviation / 100;

// DECLARE GLOBAL ARRAYS
Bull = Bull4 = Bear = Bear4 = 0;
AD_AX_min = AD_AX_max = 0;
CD_BC_min = CD_BC_max = 0;
BullBat = BearBat = BullGartley = BearGartley = BullButterfly = BearButterfly = BullCrab = BearCrab = BullABCD = BearABCD = 0;
BullAlternateBat = BearAlternateBat = BullDeepCrab = BearDeepCrab = BullCypher = BearCypher = 0;
topBox_bu = topBox_be = botBox_bu = botBox_be = 0;
P1 = V1 = 0;

// CALCULATE THE PIVOTS
pk = H == HHV( H, leftstrength ) AND Ref( HHV( H, rightstrength ), rightstrength ) < H;
P1 = pk = pk AND LastValue( bi ) - ValueWhen( pk, bi ) > rightstrength;
tr = L == LLV( L, leftstrength ) AND Ref( LLV( L, rightstrength ), rightstrength ) > L;
V1 = tr = tr AND LastValue( bi ) - ValueWhen( tr, bi ) > rightstrength;

P1 = IIf( P1, IIf( ValueWhen( P1, bi, 2 ) < ValueWhen( V1, bi ), P1, IIf( ValueWhen( P1, H, 2 ) > H, False, P1 ) ), P1 );
P1 = IIf( P1 AND ValueWhen( P1, bi, 0 ) > bi, IIf( ValueWhen( P1, bi, 0 ) < ValueWhen( V1, bi, 0 ), IIf( ValueWhen( P1, H, 0 ) >= H, False, P1 ), P1 ), P1 );
V1 = IIf( V1, IIf( ValueWhen( V1, bi, 2 ) < ValueWhen( P1, bi ), V1, IIf( ValueWhen( V1, L, 2 ) < L, False, V1 ) ), V1 );
V1 = IIf( V1 AND ValueWhen( V1, bi, 0 ) > bi , IIf( ValueWhen( V1, bi, 0 ) < ValueWhen( P1, bi, 0 ), IIf( ValueWhen( V1, L, 0 ) <= L, False, V1 ), V1 ), V1 );

// BULLISH AND BEARIH PATTERN PREPARATIONS
P1H1 = ValueWhen( P1, H );
P1Bar1 = ValueWhen( P1, bi );
P1H2 = ValueWhen( P1, H, 2 );
P1Bar2 = ValueWhen( P1, bi, 2 );
V1L1 = ValueWhen( V1, L );
V1Bar1 = ValueWhen( V1, bi );
V1L2 = ValueWhen( V1, L, 2 );
V1Bar2 = ValueWhen( V1, bi, 2 );

PTvalid_bu = ( P1Bar1 > V1Bar1 AND V1Bar1 > P1Bar2 AND P1bar2 > V1Bar2 ) AND P1;

AX_bu = P1H2 - V1L2;
AB_bu = P1H2 - V1L1;
BC_bu = P1H1 - V1L1;

AB_AX_bu = SafeDivide( AB_bu, AX_bu );
BC_AB_bu = SafeDivide( BC_bu, AB_bu );

PTvalid_be = ( V1Bar1 > P1Bar1 AND P1Bar1 > V1Bar2 AND V1Bar2 > P1Bar2 ) AND V1;

AX_be = P1H2 - V1L2;
AB_be = P1H1 - V1L2;
BC_be = P1H1 - V1L1;

AB_AX_be = SafeDivide( AB_be, AX_be );
BC_AB_be = SafeDivide( BC_be, AB_be );

// PATTERN CALCULATION AND DISPLAY FUNCTIONS
function drawHarmonicPattern( Xbar, X, Abar, A, Bbar, B, C1bar, C1, Dbar, D, ABdXA, BCdAB, ADdXA, BCdCD, topBox, botBox, patternName, clr1, clr2, clr3, fac )
{
    GfxSetZOrder( 1 );
    GfxSelectPen( clr1, 2, 0 );
    GfxMoveTo( Xbar, X );
    GfxLineTo( Abar, A );
    GfxLineTo( Bbar, B );
    GfxLineTo( C1bar, C1 );
    GfxLineTo( Dbar, D );
    GfxSelectPen( clr1, 1, dl );
    GfxMoveTo( Abar, A );
    GfxLineTo( C1bar, C1 );
    GfxMoveTo( Xbar, X );
    GfxLineTo( Bbar, B );
    GfxLineTo( Dbar, D );
    GfxLineTo( Xbar, X );

    PlotTextSetFont( NumToStr( ABdXA, 1.2 ), ft, sz, ( Bbar + Xbar ) / 2, ( B + X ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdAB, 1.2 ), ft, sz, ( C1bar + Abar ) / 2, ( C1 + A ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( ADdXA, 1.2 ), ft, sz, ( Dbar + Xbar ) / 2, ( D + X ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdCD, 1.2 ), ft, sz, ( Bbar + Dbar ) / 2, ( B + D ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( "X", ft, sz, Xbar - st, X, clr1, colorDefault, 0 );
    PlotTextSetFont( "A", ft, sz, Abar - st, A, clr1, colorDefault, 0 );
    PlotTextSetFont( "B", ft, sz, Bbar - st, B, clr1, colorDefault, 0 );
    PlotTextSetFont( "C", ft, sz, C1bar + st, C1, clr1, colorDefault, 0 );
    PlotTextSetFont( "D", ft, sz, Dbar + st, D, clr1, colorDefault, 0 );
    PlotTextSetFont( "" + patternName, ft, sz, Xbar, X, clr1, colorDefault, sz * fac );

    GfxSetZOrder( -1 );
    GfxSelectPen( clr2, 2, 0 );
    GfxSelectSolidBrush( clr3 );
    // draw PRZ rectangle
    x0 = C1bar;
    y0 = topBox;
    x1 = Dbar;
    y1 = botBox;
    GfxRectangle( x0, y0, x1, y1 );
}

function drawABCDPattern( Abar, A, Bbar, B, C1bar, C1, Dbar, D, BCdAB, BCdCD, topBox, botBox, patternName, clr1, clr2, clr3, fac )
{
    GfxSetZOrder( 1 );
    GfxSelectPen( clr1, 1, 0 );
    GfxMoveTo( Abar, A );
    GfxLineTo( Bbar, B );
    GfxLineTo( C1bar, C1 );
    GfxLineTo( Dbar, D );
    GfxSelectPen( clr1, 1, dl );
    GfxMoveTo( Abar, A );
    GfxLineTo( C1bar, C1 );
    GfxMoveTo( Bbar, B );
    GfxLineTo( Dbar, D );

    PlotTextSetFont( NumToStr( BCdAB, 1.2 ), ft, sz, ( C1bar + Abar ) / 2, ( C1 + A ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdCD, 1.2 ), ft, sz, ( Bbar + Dbar ) / 2, ( B + D ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( "A", ft, sz, Abar - st, A, clr1, colorDefault, 0 );
    PlotTextSetFont( "B", ft, sz, Bbar - st, B, clr1, colorDefault, 0 );
    PlotTextSetFont( "C", ft, sz, C1bar + st, C1, clr1, colorDefault, 0 );
    PlotTextSetFont( "D", ft, sz, Dbar + st, D, clr1, colorDefault, 0 );
    PlotTextSetFont( "" + patternName, ft, sz, Abar, A, clr1, colorDefault, sz * fac );

    // draw PRZ rectangle
    GfxSetZOrder( -1 );
    GfxSelectPen( clr2, 2, 0 );
    GfxSelectSolidBrush( clr3 );
    x0 = C1bar;
    y0 = topBox;
    x1 = Dbar;
    y1 = botBox;
    GfxRectangle( x0, y0, x1, y1 );
}

function calculateBullishHarmonicPattern( MinXB, MaxXB, MinAC, MaxAC, MinXD, MaxXD, MinBD, MaxBD )
{
    Bull4 = PTvalid_bu AND( AB_AX_bu > MinXB ) AND( AB_AX_bu < MaxXB )
            AND( BC_AB_bu > MinAC ) AND( BC_AB_bu < MaxAC );

    dHigh = HighestSince( Bull4, H );
    dLow = LowestSince( Bull4, L );

    pC = ValueWhen( Bull4, P1H1 );
    pB = ValueWhen( Bull4, V1L1 );
    pA = ValueWhen( Bull4, P1H2 );
    pX = ValueWhen( Bull4, V1L2 );
    AX = pA - pX;
    BC = pC - pB;

    if( ps )
    {
        AD_AX_min = pA - AX * MinXD;
        AD_AX_max = pA - AX * MaxXD;
        CD_BC_min = pC - BC * MinBD;
        CD_BC_max = pC - BC * MaxBD;
        topBox_bu = Min( AD_AX_min, CD_BC_min );
        botBox_bu = Max( AD_AX_max, CD_BC_max );

        Bull = IIf( ( dLow < AD_AX_min ) AND( dLow > AD_AX_max )
                    AND( dLow < CD_BC_min ) AND( dLow > CD_BC_max )
                    AND( dHigh <= pC ) AND( dLow == L ),
                    True, False );
        Bull = Bull AND( dLow < pB );
    }
    else
    {
        AD_AX_min = pA - AX * MinXD;
        AD_AX_max = pA - AX * MaxXD;
        topBox_bu = AD_AX_min;
        botBox_bu = AD_AX_max;

        Bull = IIf( ( dLow < AD_AX_min ) AND( dLow > AD_AX_max )
                    AND( dHigh <= pC ) AND( dLow == L ),
                    True, False );
        Bull = Bull AND( dLow < pB );
    }

    if( showDotsAtD )
        PlotShapes( IIf( Bull, shapeSmallCircle, Null ), ColorRGB( 64, 64, 128 ), 0, L, -20 );
}

function calculateBearishHarmonicPattern( MinXB, MaxXB, MinAC, MaxAC, MinXD, MaxXD, MinBD, MaxBD )
{
    Bear4 = PTvalid_be AND( AB_AX_be > MinXB ) AND( AB_AX_be < MaxXB )
            AND( BC_AB_be > MinAC ) AND( BC_AB_be < MaxAC );

    dHigh = HighestSince( Bear4, H );
    dLow = LowestSince( Bear4, L );

    pX = ValueWhen( Bear4, P1H2 );
    pB = ValueWhen( Bear4, P1H1 );
    pA = ValueWhen( Bear4, V1L2 );
    pC = ValueWhen( Bear4, V1L1 );
    AX = pX - pA;
    BC = pB - pC;

    if( ps )
    {
        AD_AX_min = pA + AX * MinXD;
        AD_AX_max = pA + AX * MaxXD;
        CD_BC_min = pC + BC * MinBD;
        CD_BC_max = pC + BC * MaxBD;
        botBox_be = Max( AD_AX_min, CD_BC_min );
        topBox_be = Min( AD_AX_max, CD_BC_max );

        Bear = IIf( ( dHigh > AD_AX_min ) AND( dHigh < AD_AX_max )
                    AND( dHigh > CD_BC_min ) AND( dHigh < CD_BC_max )
                    AND( dLow >= pC ) AND( dHigh == H ),
                    True, False );
        Bear = Bear AND( dHigh > pB );
    }
    else
    {
        AD_AX_min = pA + AX * MinXD;
        AD_AX_max = pA + AX * MaxXD;
        botBox_be = AD_AX_min;
        topBox_be = AD_AX_max;

        Bear = IIf( ( dHigh > AD_AX_min ) AND( dHigh < AD_AX_max )
                    AND( dLow >= pC ) AND( dHigh == H ),
                    True, False );
        Bear = Bear AND( dHigh > pB );
    }

    if( showDotsAtD )
        PlotShapes( IIf( Bear, shapeSmallCircle, Null ), ColorRGB( 128, 64, 64 ), 0, H, 20 );
}

function calculateBullishABCDPattern( MinAC, MaxAC, MinBD, MaxBD )
{
    Bull4 = PTvalid_bu AND( BC_AB_bu > MinAC ) AND( BC_AB_bu < MaxAC );

    dHigh = HighestSince( Bull4, H );
    dLow = LowestSince( Bull4, L );

    pC = ValueWhen( Bull4, P1H1 );
    pB = ValueWhen( Bull4, V1L1 );
    pA = ValueWhen( Bull4, P1H2 );
    pX = ValueWhen( Bull4, V1L2 );
    CB = pC - pB;

    CD_BC_min = pC - CB * MinBD;
    CD_BC_max = pC - CB * MaxBD;

    Bull = IIf( ( dLow < CD_BC_min ) AND( dLow > CD_BC_max )
                AND( dHigh <= pC ) AND( dLow == L ),
                True, False );
    Bull = Bull AND( dLow < pB );

    if( showDotsAtD )
        PlotShapes( IIf( Bull, shapeSmallCircle, Null ), ColorRGB( 64, 128, 64 ), 0, L, -20 );
}

function calculateBearishABCDPattern( MinAC, MaxAC, MinBD, MaxBD )
{
    Bear4 = PTvalid_be AND( BC_AB_be > MinAC ) AND( BC_AB_be < MaxAC );

    dHigh = HighestSince( Bear4, H );
    dLow = LowestSince( Bear4, L );

    pA = ValueWhen( Bear4, V1L2 );
    pB = ValueWhen( Bear4, P1H1 );
    pC = ValueWhen( Bear4, V1L1 );
    CB = pB - pC;

    CD_BC_min = pC + CB * MinBD;
    CD_BC_max = pC + CB * MaxBD;

    Bear = IIf( ( dHigh > CD_BC_min ) AND( dHigh < CD_BC_max )
                AND( dLow >= pC ) AND( dHigh == H ),
                True, False );
    Bear = Bear AND( dHigh > pB );

    if( showDotsAtD )
        PlotShapes( IIf( Bear, shapeSmallCircle, Null ), ColorRGB( 128, 128, 64 ), 0, H, 20 );
}

function showBullishHarmonicPattern( patternName )
{
    BullHar4 = Bull4;
    BullHar = Bull;
    rBullHar4 = Reverse( BullHar4, 0, lvb );
    rBullHar = Reverse( BullHar, 0, lvb );
    rBullHar = ExRem( rBullHar, rBullHar4 );
    BullHar = Reverse( rBullHar, 0, lvb );
    X = ValueWhen( BullHar4, V1L2 );
    Xbar = ValueWhen( BullHar4, V1Bar2 );
    A = ValueWhen( BullHar4, P1H2 );
    Abar = ValueWhen( BullHar4, P1bar2 );
    B = ValueWhen( BullHar4, V1L1 );
    Bbar = ValueWhen( BullHar4, V1bar1 );
    C1 = ValueWhen( BullHar4, P1H1 );
    C1bar = ValueWhen( BullHar4, P1bar1 );
    D = ValueWhen( BullHar, L );
    Dbar = ValueWhen( BullHar, bi );
    ABdXA = SafeDivide( A - B, A - X );
    BCdAB = SafeDivide( C1 - B, A - B );
    ADdXA = SafeDivide( A - D, A - X );
    BCdCD = SafeDivide( C1 - D, C1 - B );

    for( i = lvb; i > fvb; i-- )
    {
        if( BullHar[i] )
        {
            drawHarmonicPattern( Xbar[i], X[i], Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i],
                                 D[i], ABdXA[i], BCdAB[i], ADdXA[i], BCdCD[i], topBox_bu[i], botBox_bu[i],
                                 patternName, ColorRGB( 0, 0, 255 ), ColorRGB( 0, 0, 120 ), ColorRGB( 0, 0, 30 ), -2 );
        }
    }
}

function showBearishHarmonicPattern( patternName )
{
    BearHar4 = Bear4;
    BearHar = Bear;
    rBearHar4 = Reverse( BearHar4, 0, lvb );
    rBearHar = Reverse( BearHar, 0, lvb );
    rBearHar = ExRem( rBearHar, rBearHar4 );
    BearHar = Reverse( rBearHar, 0, lvb );
    X = ValueWhen( BearHar4, P1H2 );
    Xbar = ValueWhen( BearHar4, P1Bar2 );
    A = ValueWhen( BearHar4, V1L2 );
    Abar = ValueWhen( BearHar4, V1bar2 );
    B = ValueWhen( BearHar4, P1H1 );
    Bbar = ValueWhen( BearHar4, P1bar1 );
    C1 = ValueWhen( BearHar4, V1L1 );
    C1bar = ValueWhen( BearHar4, V1bar1 );
    D = ValueWhen( BearHar, H );
    Dbar = ValueWhen( BearHar, bi );
    ABdXA = SafeDivide( B - A, X - A );
    BCdAB = SafeDivide( B - C1, B - A );
    ADdXA = SafeDivide( D - A, X - A );
    BCdCD = SafeDivide( D - C1, B - C1 );

    for( i = lvb; i > fvb; i-- )
    {
        bearcolor = colorRed;
        linethick = 1;

        if( BearHar[i] )
        {
            drawHarmonicPattern( Xbar[i], X[i], Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i],
                                 D[i], ABdXA[i], BCdAB[i], ADdXA[i], BCdCD[i], topBox_be[i], botBox_be[i],
                                 patternName, ColorRGB( 255, 0, 0 ), ColorRGB( 120, 0, 0 ), ColorRGB( 30, 0, 0 ), 1 );
        }
    }
}

function showBullishABCDPattern( patternName )
{
    BullHar4 = Bull4;
    BullHar = Bull;
    rBullHar4 = Reverse( BullHar4, 0, lvb );
    rBullHar = Reverse( BullHar, 0, lvb );
    rBullHar = ExRem( rBullHar, rBullHar4 );
    BullHar = Reverse( rBullHar, 0, lvb );
    A = ValueWhen( BullHar4, P1H2 );
    Abar = ValueWhen( BullHar4, P1bar2 );
    B = ValueWhen( BullHar4, V1L1 );
    Bbar = ValueWhen( BullHar4, V1bar1 );
    C1 = ValueWhen( BullHar4, P1H1 );
    C1bar = ValueWhen( BullHar4, P1bar1 );
    D = ValueWhen( BullHar, L );
    Dbar = ValueWhen( BullHar, bi );
    BCdAB = SafeDivide( C1 - B, A - B );
    BCdCD = SafeDivide( C1 - D, C1 - B );

    for( i = lvb; i > fvb; i-- )
    {
        bullcolor = colorGreen;
        linethick = 1;

        if( BullHar[i] AND bu )
        {
            drawABCDPattern( Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i], D[i], BCdAB[i], BCdCD[i],
                             CD_BC_min[i], CD_BC_max[i], patternName, ColorGreen, ColorRGB( 0, 80, 0 ), ColorRGB( 0, 10, 0 ), 1 );
        }
    }
}

function showBearishABCDPattern( patternName )
{
    BearHar4 = Bear4;
    BearHar = Bear;
    rBearHar4 = Reverse( BearHar4, 0, lvb );
    rBearHar = Reverse( BearHar, 0, lvb );
    rBearHar = ExRem( rBearHar, rBearHar4 );
    BearHar = Reverse( rBearHar, 0, lvb );
    A = ValueWhen( BearHar4, V1L2 );
    Abar = ValueWhen( BearHar4, V1bar2 );
    B = ValueWhen( BearHar4, P1H1 );
    Bbar = ValueWhen( BearHar4, P1bar1 );
    C1 = ValueWhen( BearHar4, V1L1 );
    C1bar = ValueWhen( BearHar4, V1bar1 );
    D = ValueWhen( BearHar, H );
    Dbar = ValueWhen( BearHar, bi );
    BCdAB = SafeDivide( B - C1, B - A );
    BCdCD = SafeDivide( D - C1, B - C1 );

    for( i = lvb; i > fvb; i-- )
    {
        bearcolor = colorYellow;
        linethick = 1;

        if( BearHar[i] AND be )
        {
            drawABCDPattern( Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i], D[i], BCdAB[i], BCdCD[i],
                             CD_BC_min[i], CD_BC_max[i], patternName, ColorYellow, ColorRGB( 80, 80, 0 ), ColorRGB( 10, 10, 0 ), -2 );
        }
    }
}

// DISPLAY
SetChartOptions( 0, chartShowArrows | chartShowDates );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );
Plot( C, "", colorWhite, styleCandle, Null, Null, 0, 1 );

if( bu )
{
    if( showGartley ) // #1
    {
        // Bullish Gartley Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Gartley_MinXB, Gartley_MaxXB, Gartley_MinAC, Gartley_MaxAC, Gartley_MinXD, Gartley_MaxXD, Gartley_MinBD, Gartley_MaxBD );
        showBullishHarmonicPattern( "Bullish Gartley" );
        BullGartley = Bull;
    }

    if( showBat )
    {
        // Bullish Bat Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Bat_MinXB, Bat_MaxXB, Bat_MinAC, Bat_MaxAC, Bat_MinXD, Bat_MaxXD, Bat_MinBD, Bat_MaxBD );
        showBullishHarmonicPattern( "Bullish Bat" );
        BullBat = Bull;
    }

    if( showAlternateBat )
    {
        // Bullish Alternate Bat Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( AlternateBat_MinXB, AlternateBat_MaxXB, AlternateBat_MinAC, AlternateBat_MaxAC, AlternateBat_MinXD, AlternateBat_MaxXD, AlternateBat_MinBD, AlternateBat_MaxBD );
        showBullishHarmonicPattern( "Bullish Alternate Bat" );
        BullAlternateBat = Bull;
    }

    if( showButterfly )
    {
        // Bullish Butterfly Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Butterfly_MinXB, Butterfly_MaxXB, Butterfly_MinAC, Butterfly_MaxAC, Butterfly_MinXD, Butterfly_MaxXD, Butterfly_MinBD, Butterfly_MaxBD );
        showBullishHarmonicPattern( "Bullish Butterfly" );
        BullButterfly = Bull;
    }

    if( showCrab )
    {
        // Bullish Crab Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Crab_MinXB, Crab_MaxXB, Crab_MinAC, Crab_MaxAC, Crab_MinXD, Crab_MaxXD, Crab_MinBD, Crab_MaxBD );
        showBullishHarmonicPattern( "Bullish Crab" );
        BullCrab = Bull;
    }

    if( showDeepCrab )
    {
        // Bullish DeepCrab Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( DeepCrab_MinXB, DeepCrab_MaxXB, DeepCrab_MinAC, DeepCrab_MaxAC, DeepCrab_MinXD, DeepCrab_MaxXD, DeepCrab_MinBD, DeepCrab_MaxBD );
        showBullishHarmonicPattern( "Bullish Deep Crab" );
        BullDeepCrab = Bull;
    }

    if( showCypher )
    {
        // Bullish Cypher Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Cypher_MinXB, Cypher_MaxXB, Cypher_MinAC, Cypher_MaxAC, Cypher_MinXD, Cypher_MaxXD, Cypher_MinBD, Cypher_MaxBD );
        showBullishHarmonicPattern( "Bullish Cypher" );
        BullCypher = Bull;
    }

    if( showABCD )
    {
        // Bullish ABCD Pattern
        Bull = Bull4 = 0;
        CD_BC_min = CD_BC_max = 0;
        calculateBullishABCDPattern( ABCD_MinAC, ABCD_MaxAC, ABCD_MinBD, ABCD_MaxBD );
        showBullishABCDPattern( "Bullish ABCD" );
        BullABCD = Bull;
    }
}

if( be )
{
    if( showGartley )
    {
        // Bearish Gartley Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Gartley_MinXB, Gartley_MaxXB, Gartley_MinAC, Gartley_MaxAC, Gartley_MinXD, Gartley_MaxXD, Gartley_MinBD, Gartley_MaxBD );
        showBearishHarmonicPattern( "Bearish Gartley" );
        BearGartley = Bear;
    }

    if( showBat )
    {
        // Bearish Bat Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Bat_MinXB, Bat_MaxXB, Bat_MinAC, Bat_MaxAC, Bat_MinXD, Bat_MaxXD, Bat_MinBD, Bat_MaxBD );
        showBearishHarmonicPattern( "Bearish Bat" );
        BearBat = Bear;
    }

    if( showAlternateBat )
    {
        // Bearish Alternate Bat Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( AlternateBat_MinXB, AlternateBat_MaxXB, AlternateBat_MinAC, AlternateBat_MaxAC, AlternateBat_MinXD, AlternateBat_MaxXD, AlternateBat_MinBD, AlternateBat_MaxBD );
        showBearishHarmonicPattern( "Bearish Alternate Bat" );
        BearAlternateBat = Bear;
    }

    if( showButterfly )
    {
        // Bearish Butterfly Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Butterfly_MinXB, Butterfly_MaxXB, Butterfly_MinAC, Butterfly_MaxAC, Butterfly_MinXD, Butterfly_MaxXD, Butterfly_MinBD, Butterfly_MaxBD );
        showBearishHarmonicPattern( "Bearish Butterfly" );
        BearButterfly = Bear;
    }

    if( showCrab )
    {
        // Bearish Crab Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Crab_MinXB, Crab_MaxXB, Crab_MinAC, Crab_MaxAC, Crab_MinXD, Crab_MaxXD, Crab_MinBD, Crab_MaxBD );
        showBearishHarmonicPattern( "Bearish Crab" );
        BearCrab = Bear;
    }

    if( showDeepCrab )
    {
        // Bearish Deep Crab Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( DeepCrab_MinXB, DeepCrab_MaxXB, DeepCrab_MinAC, DeepCrab_MaxAC, DeepCrab_MinXD, DeepCrab_MaxXD, DeepCrab_MinBD, DeepCrab_MaxBD );
        showBearishHarmonicPattern( "Bearish Deep Crab" );
        BearDeepCrab = Bear;
    }

    if( showCypher )
    {
        // Bearish Cypher Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Cypher_MinXB, Cypher_MaxXB, Cypher_MinAC, Cypher_MaxAC, Cypher_MinXD, Cypher_MaxXD, Cypher_MinBD, Cypher_MaxBD );
        showBearishHarmonicPattern( "Bearish Cypher" );
        BearCypher = Bear;
    }

    if( showABCD )
    {
        // Bearish ABCD Pattern
        Bull = Bull4 = 0;
        CD_BC_min = CD_BC_max = 0;
        calculateBearishABCDPattern( ABCD_MinAC, ABCD_MaxAC, ABCD_MinBD, ABCD_MaxBD );
        showBearishABCDPattern( "Bearish ABCD" );
        BearABCD = Bear;
    }
}

if( PlotFractals )
{
    PlotShapes( shapeSmallCircle * P1, colorRed, 0, H, 10 );
    PlotShapes( shapeSmallCircle * V1, colorBlue, 0, L, -10 );
}

// EXPLORATION
if( Status( "action" ) == actionExplore )
{
    Filter = (
                 BullBat OR BearBat
                 OR BullGartley OR BearGartley
                 OR BullButterfly OR BearButterfly
                 OR BullCrab OR BearCrab
                 OR BullABCD OR BearABCD
                 OR BullAlternateBat OR BearAlternateBat
                 OR BullDeepCrab OR BearDeepCrab
                 OR BullCypher OR BearCypher );

    PatternDirection =
        IIf( BullGartley, 1,
             IIf( BearGartley, -1,
                  IIf( BullBat, 1,
                       IIf( BearBat, -1,
                            IIf( BullButterfly, 1,
                                 IIf( BearButterfly, -1,
                                      IIf( BullCrab, 1,
                                           IIf( BearCrab, -1,
                                                   IIf( BullABCD, 1,
                                                           IIf( BearABCD, -1,
                                                                   IIf( BullAlternateBat, 1,
                                                                           IIf( BearAlternateBat, -1,
                                                                                   IIf( BullDeepCrab, 1,
                                                                                           IIf( BearDeepCrab, -1,
                                                                                                   IIf( BullCypher, 1,
                                                                                                           IIf( BearCypher, -1 , 0 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) );
    TextColor = IIf( patternDirection > 0, ColorRGB( 0, 255, 0 ), ColorRGB( 255, 0, 0 ) );
    PatternValue =
        IIf( BullGartley, 1,
             IIf( BearGartley, 2,
                  IIf( BullBat, 3,
                       IIf( BearBat, 4,
                            IIf( BullButterfly, 5,
                                 IIf( BearButterfly, 6,
                                      IIf( BullCrab, 7,
                                           IIf( BearCrab, 8,
                                                   IIf( BullABCD, 9,
                                                           IIf( BearABCD, 10,
                                                                   IIf( BullAlternateBat, 11,
                                                                           IIf( BearAlternateBat, 12,
                                                                                   IIf( BullDeepCrab, 13,
                                                                                           IIf( BearDeepCrab, 14,
                                                                                                   IIf( BullCypher, 15,
                                                                                                           IIf( BearCypher, 16 , 0 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) );

    PatternList = "None\nBullish Gartley\nBearish Gartley" +
                  "\nBullish Bat\nBearish Bat" +
                  "\nBullish Butterfly\nBearish Butterfly" +
                  "\nBullish Crab\nBearish Crab" +
                  "\nBullish ABCD\nBearish ABCD" +
                  "\nBullish Alternate Bat\nBearish Alternate Bat" +
                  "\nBullish Deep Crab\nBearish Deep Crab" +
                  "\nBullish Cyper\nBearish Cypher";


    AddMultiTextColumn( PatternValue, PatternList, "Pattern Name", 1.0, TextColor, colorWhite, 125 ); // version 6.2 and Higher
}

_SECTION_END();
6 Likes

i made some small cosmetic changes. Often a harmonic pattern overlaps with an ABCD pattern. I made that better visible. Also the letter labels and the pattern label I made a bit nicer. So you can add more harmonic patterns when you look up the parameters MinXB, MaxXB etc. I think the PointZero guy defined 19 patterns. Sometimes more than 1 Harmonic pattern overlaps. That looks messy but I will leave that for now.

here an example how the ABCD pattern overlaps with the Bat pattern. Someone suggested to add the Sperm Whale pattern. Not sure that one exists :grinning:

_SECTION_BEGIN( "Harmonic patterns" );
/*
ratio labels
AB_AX means the ratio (A-B)/(A-X). It is the retracement of A to B over the price range A to X
BC_AB means the ratio (C-B)/(A-B)
CD_BC means the ratio (C-D)/(C-B)
AD_AX means the ratio (A-D)/(A-X)
*/

GfxSetZOrder( -5 );
GfxSetCoordsMode( 1 );

bi = BarIndex();
fvb = FirstVisibleValue( Ref( bi, -0 ) );
lvb = LastVisibleValue( Ref( bi, -1 ) );

// PARAMETERS
rightstrength = Param( "Right Strength", 10, 2, 50, 1 );
leftstrength = Param( "Left Strength", 10, 2, 50, 1 );
bu = ParamToggle( "Bullish Pattern", "Off|On", 1 );
be = ParamToggle( "Bearish Pattern", "Off|On", 1 );
showABCD = ParamToggle( "Show ABCD", "Off|On", 1 );
showGartley = ParamToggle( "Show Gartley", "Off|On", 0 );
showBat = ParamToggle( "Show Bat", "Off|On", 0 );
showAlternateBat = ParamToggle( "Show Alternate Bat", "Off|On", 0 );
showButterfly = ParamToggle( "Show Butterfly", "Off|On", 0 );
showCrab = ParamToggle( "Show Crab", "Off|On", 0 );
showDeepCrab = ParamToggle( "Show Deep Crab", "Off|On", 0 );
showCypher = ParamToggle( "Show Cypher", "Off|On", 0 );
ft = ParamList( "Font Type", "Tahoma|Arial Black|Verdana|Courier New|Times New Roman|Open Sans|Segoe UI|DejaVu Sans", 6 );
sz = Param( "Font Size", 12, 8, 50, 1 );
ftw = Param( " Font Weight", 400, 0, 900, 100 );
st = Param( "Separation of Letters", 3, 1, 10, 1 );
dl = Param( "Dashed Line Number", 2, 1, 4, 1 );
showDotsAtD = ParamToggle( "Show Dots at D", "Off|On", 1 );
showPatternName = ParamToggle( "Show Pattern Name", "Off|On", 1 );
loc = Param( "Pattern Name Position", 6, 1, 10, 0.1 );
plotFractals = ParamToggle( "Plot Fractal Pivot Points", "Off|On", 1 );
ps = ParamToggle( "Swing D constraint", "use only AD_AX contraint|use both AD_AX AND CB_BC constraint", 1 );
deviation = Param( "Deviation", 10, 0.1, 100, 0.1 );


// Gartley
Gartley_MinXB = 0.618 - 0.618 * deviation / 100; // retrace from A to B over distance X to A
Gartley_MaxXB = 0.618 + 0.618 * deviation / 100;
Gartley_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Gartley_MaxAC = 0.886 + 0.886 * deviation / 100;
Gartley_MinBD = 1.13 - 1.13 * deviation / 100; // retrace from C to D over distance B to C
Gartley_MaxBD = 1.618 + 1.618 * deviation / 100;
Gartley_MinXD = 0.786 - 0.786 * deviation / 100; // retrace from A to D over distance X to A
Gartley_MaxXD = 0.786 + 0.786 * deviation / 100;

// Bat
Bat_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Bat_MaxXB = 0.5 + 0.5 * deviation / 100;
Bat_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Bat_MaxAC = 0.886 + 0.886 * deviation / 100;
Bat_MinBD = 1.618 - 1.618 * deviation / 100; // retrace from C to D over distance B to C
Bat_MaxBD = 2.618 + 2.618 * deviation / 100;
Bat_MinXD = 0.886 - 0.886 * deviation / 100; // retrace from A to D over distance X to A
Bat_MaxXD = 0.886 + 0.886 * deviation / 100;

// Alternate Bat
AlternateBat_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
AlternateBat_MaxXB = 0.382 + 0.382 * deviation / 100;
AlternateBat_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
AlternateBat_MaxAC = 0.886 + 0.886 * deviation / 100;
AlternateBat_MinBD = 2.0 - 2.0 * deviation / 100; // retrace from C to D over distance B to C
AlternateBat_MaxBD = 3.618 + 3.618 * deviation / 100;
AlternateBat_MinXD = 1.13 - 1.13 * deviation / 100; // retrace from A to D over distance X to A
AlternateBat_MaxXD = 1.13 + 1.13 * deviation / 100;

// Butterfly
Butterfly_MinXB = 0.786 - 0.786 * deviation / 100; // retrace from A to B over distance X to A
Butterfly_MaxXB = 0.786 + 0.786 * deviation / 100;
Butterfly_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Butterfly_MaxAC = 0.886 + 0.886 * deviation / 100;
Butterfly_MinBD = 1.618 - 1.618 * deviation / 100; // retrace from C to D over distance B to C
Butterfly_MaxBD = 2.24 + 2.24 * deviation / 100;
Butterfly_MinXD = 1.27 - 1.27 * deviation / 100; // retrace from A to D over distance X to A
Butterfly_MaxXD = 1.27 + 1.27 * deviation / 100;

// Crab
Crab_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Crab_MaxXB = 0.618 + 0.618 * deviation / 100;
Crab_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Crab_MaxAC = 0.886 + 0.886 * deviation / 100;
Crab_MinBD = 2.618 - 2.618 * deviation / 100; // retrace from C to D over distance B to C
Crab_MaxBD = 3.618 + 3.618 * deviation / 100;
Crab_MinXD = 1.618 - 1.618 * deviation / 100; // retrace from A to D over distance X to A
Crab_MaxXD = 1.618 + 1.618 * deviation / 100;

// Deep Crab
DeepCrab_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
DeepCrab_MaxXB = 0.618 + 0.618 * deviation / 100;
DeepCrab_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
DeepCrab_MaxAC = 0.886 + 0.886 * deviation / 100;
DeepCrab_MinBD = 2.618 - 2.618 * deviation / 100; // retrace from C to D over distance B to C
DeepCrab_MaxBD = 3.618 + 3.618 * deviation / 100;
DeepCrab_MinXD = 1.618 - 1.618 * deviation / 100; // retrace from A to D over distance X to A
DeepCrab_MaxXD = 1.618 + 1.618 * deviation / 100;

// Cypher
Cypher_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Cypher_MaxXB = 0.618 + 0.618 * deviation / 100;
Cypher_MinAC = 1.13 - 1.13 * deviation / 100; // retrace from B to C over distance A to B
Cypher_MaxAC = 1.414 + 1.414 * deviation / 100;
Cypher_MinBD = 1.272 - 1.272 * deviation / 100; // retrace from C to D over distance B to C
Cypher_MaxBD = 2.0 + 2.0 * deviation / 100;
Cypher_MinXD = 0.786 - 0.786 * deviation / 100; // retrace from A to D over distance X to A
Cypher_MaxXD = 0.786 + 0.786 * deviation / 100;

ABCD_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
ABCD_MaxAC = 0.886 + 0.886 * deviation / 100;
ABCD_MinBD = 1.13 - 1.13 * deviation / 100; // retrace from C to D over distance B to C
ABCD_MaxBD = 2.618 + 2.618 * deviation / 100;

// DECLARE GLOBAL ARRAYS
Bull = Bull4 = Bear = Bear4 = 0;
AD_AX_min = AD_AX_max = 0;
CD_BC_min = CD_BC_max = 0;
BullBat = BearBat = BullGartley = BearGartley = BullButterfly = BearButterfly = BullCrab = BearCrab = BullABCD = BearABCD = 0;
BullAlternateBat = BearAlternateBat = BullDeepCrab = BearDeepCrab = BullCypher = BearCypher = 0;
topBox_bu = topBox_be = botBox_bu = botBox_be = 0;
P1 = V1 = 0;

// CALCULATE THE PIVOTS
pk = H == HHV( H, leftstrength ) AND Ref( HHV( H, rightstrength ), rightstrength ) < H;
P1 = pk = pk AND LastValue( bi ) - ValueWhen( pk, bi ) > rightstrength;
tr = L == LLV( L, leftstrength ) AND Ref( LLV( L, rightstrength ), rightstrength ) > L;
V1 = tr = tr AND LastValue( bi ) - ValueWhen( tr, bi ) > rightstrength;

P1 = IIf( P1, IIf( ValueWhen( P1, bi, 2 ) < ValueWhen( V1, bi ), P1, IIf( ValueWhen( P1, H, 2 ) > H, False, P1 ) ), P1 );
P1 = IIf( P1 AND ValueWhen( P1, bi, 0 ) > bi, IIf( ValueWhen( P1, bi, 0 ) < ValueWhen( V1, bi, 0 ), IIf( ValueWhen( P1, H, 0 ) >= H, False, P1 ), P1 ), P1 );
V1 = IIf( V1, IIf( ValueWhen( V1, bi, 2 ) < ValueWhen( P1, bi ), V1, IIf( ValueWhen( V1, L, 2 ) < L, False, V1 ) ), V1 );
V1 = IIf( V1 AND ValueWhen( V1, bi, 0 ) > bi , IIf( ValueWhen( V1, bi, 0 ) < ValueWhen( P1, bi, 0 ), IIf( ValueWhen( V1, L, 0 ) <= L, False, V1 ), V1 ), V1 );

// BULLISH AND BEARISH PATTERN PREPARATIONS
P1H1 = ValueWhen( P1, H );
P1Bar1 = ValueWhen( P1, bi );
P1H2 = ValueWhen( P1, H, 2 );
P1Bar2 = ValueWhen( P1, bi, 2 );
V1L1 = ValueWhen( V1, L );
V1Bar1 = ValueWhen( V1, bi );
V1L2 = ValueWhen( V1, L, 2 );
V1Bar2 = ValueWhen( V1, bi, 2 );

PTvalid_bu = ( P1Bar1 > V1Bar1 AND V1Bar1 > P1Bar2 AND P1bar2 > V1Bar2 ) AND P1;

AX_bu = P1H2 - V1L2;
AB_bu = P1H2 - V1L1;
BC_bu = P1H1 - V1L1;

AB_AX_bu = SafeDivide( AB_bu, AX_bu );
BC_AB_bu = SafeDivide( BC_bu, AB_bu );

PTvalid_be = ( V1Bar1 > P1Bar1 AND P1Bar1 > V1Bar2 AND V1Bar2 > P1Bar2 ) AND V1;

AX_be = P1H2 - V1L2;
AB_be = P1H1 - V1L2;
BC_be = P1H1 - V1L1;

AB_AX_be = SafeDivide( AB_be, AX_be );
BC_AB_be = SafeDivide( BC_be, AB_be );

// PATTERN CALCULATION AND DISPLAY FUNCTIONS
function GfxConvertBarToPixelX( bar )
{
    local fvb1, lvb1;

    lvb1 = Status( "lastvisiblebar" );
    fvb1 = Status( "firstvisiblebar" );
    pxchartleft = Status( "pxchartleft" );
    pxchartwidth = Status( "pxchartwidth" );

    return pxchartleft + bar  * pxchartwidth / ( lvb1 - fvb1 + 1 );
}

function GfxConvertValueToPixelY( Value )
{
    local Miny, Maxy, pxchartbottom, pxchartheight;

    Miny = Status( "axisminy" );
    Maxy = Status( "axismaxy" );

    pxchartbottom = Status( "pxchartbottom" );
    pxchartheight = Status( "pxchartheight" );

    return pxchartbottom - floor( 0.5 + ( Value - Miny ) * pxchartheight / ( Maxy - Miny ) );
}

function CalculateAngle( x1, y1, x2, y2 )
{
    // calculate angle of text
    x1 = GfxConvertBarToPixelX( x1 );
    y1 = GfxConvertValueToPixelY( y1 );
    x2 = GfxConvertBarToPixelX( x2 );
    y2 = GfxConvertValueToPixelY( y2 );
    onerad = 57.2957795;
    angle = 10 * onerad * atan( ( y2 - y1 ) / ( x2 - x1 ) ) * -1;
    return angle;
}

function drawHarmonicPattern( Xbar, X, Abar, A, Bbar, B, C1bar, C1, Dbar, D, ABdXA, BCdAB, ADdXA, BCdCD, topBox, botBox, patternName, clr1, clr2, clr3, fac, dir )
{
    GfxSetZOrder( 1 );
    GfxSelectPen( clr1, 2, 0 );
    GfxMoveTo( Xbar, X );
    GfxLineTo( Abar, A );
    GfxLineTo( Bbar, B );
    GfxLineTo( C1bar, C1 );
    GfxLineTo( Dbar, D );
    GfxSelectPen( clr1, 1, dl );
    GfxMoveTo( Abar, A );
    GfxLineTo( C1bar, C1 );
    GfxMoveTo( Xbar, X );
    GfxLineTo( Bbar, B );
    GfxLineTo( Dbar, D );
    GfxLineTo( Xbar, X );

    PlotTextSetFont( NumToStr( ABdXA, 1.2 ), ft, sz, ( Bbar + Xbar ) / 2, ( B + X ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdAB, 1.2 ), ft, sz, ( C1bar + Abar ) / 2, ( C1 + A ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( ADdXA, 1.2 ), ft, sz, ( Dbar + Xbar ) / 2, ( D + X ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdCD, 1.2 ), ft, sz, ( Bbar + Dbar ) / 2, ( B + D ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( "X", ft, sz, Xbar - st, X, clr1, colorDefault, 0 );
    PlotTextSetFont( "A", ft, sz, Abar - st, A, clr1, colorDefault, 0 );
    PlotTextSetFont( "B", ft, sz, Bbar - st, B, clr1, colorDefault, 0 );
    PlotTextSetFont( "C", ft, sz, C1bar + st, C1, clr1, colorDefault, 0 );
    PlotTextSetFont( "D", ft, sz, Dbar + st, D, clr1, colorDefault, 0 );

    if( showPatternName )
    {
        //PlotTextSetFont( "" + patternName, ft, sz, Xbar + 5, X, clr1, colorDefault, -1 * sz * fac );
        angle = calculateAngle( XBar, X, DBar, D );
        GfxSelectFont( ft, sz, ftw, False, False, angle );
        GfxSetCoordsMode( 1 );
        GfxSetTextColor( clr1 );
        GfxTextOut( "" + patternName, Xbar + ( Dbar - Xbar ) / loc, X + ( D - X ) / loc );
    }

    // draw PRZ rectangle
    GfxSetZOrder( -1 );
    GfxSelectPen( clr2, 2, 0 );
    GfxSelectSolidBrush( clr3 );
    x0 = C1bar;
    y0 = topBox;
    x1 = Dbar;
    y1 = botBox;
    GfxRectangle( x0, y0, x1, y1 );
}

function drawABCDPattern( Abar, A, Bbar, B, C1bar, C1, Dbar, D, BCdAB, BCdCD, topBox, botBox, patternName, clr1, clr2, clr3, fac, dir )
{
    GfxSetZOrder( 3 );
    GfxSelectPen( clr1, 2, 0 );
    GfxMoveTo( Abar, A );
    GfxLineTo( Bbar, B );
    GfxLineTo( C1bar, C1 );
    GfxLineTo( Dbar, D );
    GfxSelectPen( clr1, 1, dl );
    GfxMoveTo( Abar, A );
    GfxLineTo( C1bar, C1 );
    GfxMoveTo( Bbar, B );
    GfxLineTo( Dbar, D );

    PlotTextSetFont( NumToStr( BCdAB, 1.2 ), ft, sz, ( C1bar + Abar ) / 2, ( C1 + A ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdCD, 1.2 ), ft, sz, ( Bbar + Dbar ) / 2, ( B + D ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( "A", ft, sz, Abar - st, A, clr1, colorDefault, sz * dir );
    PlotTextSetFont( "B", ft, sz, Bbar - st, B, clr1, colorDefault, -sz * dir );
    PlotTextSetFont( "C", ft, sz, C1bar + st, C1, clr1, colorDefault, sz * dir );
    PlotTextSetFont( "D", ft, sz, Dbar + st, D, clr1, colorDefault, - sz * dir );

    if( showPatternName )
    {
        //PlotTextSetFont( "" + patternName, ft, sz, Abar, A, clr1, colorDefault, sz * fac );

        if( dir == 1 )
        {
            angle = calculateAngle( ABar, A, C1Bar, C1 );
            GfxSelectFont( ft, sz, ftw, False, False, angle );
            GfxSetCoordsMode( 1 );
            GfxSetTextColor( clr1 );
            GfxTextOut( "" + patternName, Abar + ( C1bar - Abar ) / loc, A + ( C1 - A ) / loc );
        }

        if( dir == ( -1 ) )
        {
            angle = calculateAngle( BBar, B, DBar, D );
            GfxSelectFont( ft, sz, ftw, False, False, angle );
            GfxSetCoordsMode( 1 );
            GfxSetTextColor( clr1 );
            GfxTextOut( "" + patternName, Bbar + ( Dbar - Bbar ) / loc, B + ( D - B ) / loc );
        }
    }

    // draw PRZ rectangle
    GfxSetZOrder( -1 );
    GfxSelectPen( clr2, 2, 0 );
    GfxSelectSolidBrush( clr3 );
    x0 = C1bar;
    y0 = topBox;
    x1 = Dbar;
    y1 = botBox;
    GfxRectangle( x0, y0, x1, y1 );
}

function calculateBullishHarmonicPattern( MinXB, MaxXB, MinAC, MaxAC, MinXD, MaxXD, MinBD, MaxBD )
{
    Bull4 = PTvalid_bu AND( AB_AX_bu > MinXB ) AND( AB_AX_bu < MaxXB )
            AND( BC_AB_bu > MinAC ) AND( BC_AB_bu < MaxAC );

    dHigh = HighestSince( Bull4, H );
    dLow = LowestSince( Bull4, L );

    pC = ValueWhen( Bull4, P1H1 );
    pB = ValueWhen( Bull4, V1L1 );
    pA = ValueWhen( Bull4, P1H2 );
    pX = ValueWhen( Bull4, V1L2 );
    AX = pA - pX;
    BC = pC - pB;

    if( ps )
    {
        AD_AX_min = pA - AX * MinXD;
        AD_AX_max = pA - AX * MaxXD;
        CD_BC_min = pC - BC * MinBD;
        CD_BC_max = pC - BC * MaxBD;
        topBox_bu = Min( AD_AX_min, CD_BC_min );
        botBox_bu = Max( AD_AX_max, CD_BC_max );

        Bull = IIf( ( dLow < AD_AX_min ) AND( dLow > AD_AX_max )
                    AND( dLow < CD_BC_min ) AND( dLow > CD_BC_max )
                    AND( dHigh <= pC ) AND( dLow == L ),
                    True, False );
        Bull = Bull AND( dLow < pB );
    }
    else
    {
        AD_AX_min = pA - AX * MinXD;
        AD_AX_max = pA - AX * MaxXD;
        topBox_bu = AD_AX_min;
        botBox_bu = AD_AX_max;

        Bull = IIf( ( dLow < AD_AX_min ) AND( dLow > AD_AX_max )
                    AND( dHigh <= pC ) AND( dLow == L ),
                    True, False );
        Bull = Bull AND( dLow < pB );
    }

    if( showDotsAtD )
        PlotShapes( IIf( Bull, shapeSmallCircle, Null ), ColorRGB( 64, 64, 128 ), 0, L, -20 );
}

function calculateBearishHarmonicPattern( MinXB, MaxXB, MinAC, MaxAC, MinXD, MaxXD, MinBD, MaxBD )
{
    Bear4 = PTvalid_be AND( AB_AX_be > MinXB ) AND( AB_AX_be < MaxXB )
            AND( BC_AB_be > MinAC ) AND( BC_AB_be < MaxAC );

    dHigh = HighestSince( Bear4, H );
    dLow = LowestSince( Bear4, L );

    pX = ValueWhen( Bear4, P1H2 );
    pB = ValueWhen( Bear4, P1H1 );
    pA = ValueWhen( Bear4, V1L2 );
    pC = ValueWhen( Bear4, V1L1 );
    AX = pX - pA;
    BC = pB - pC;

    if( ps )
    {
        AD_AX_min = pA + AX * MinXD;
        AD_AX_max = pA + AX * MaxXD;
        CD_BC_min = pC + BC * MinBD;
        CD_BC_max = pC + BC * MaxBD;
        botBox_be = Max( AD_AX_min, CD_BC_min );
        topBox_be = Min( AD_AX_max, CD_BC_max );

        Bear = IIf( ( dHigh > AD_AX_min ) AND( dHigh < AD_AX_max )
                    AND( dHigh > CD_BC_min ) AND( dHigh < CD_BC_max )
                    AND( dLow >= pC ) AND( dHigh == H ),
                    True, False );
        Bear = Bear AND( dHigh > pB );
    }
    else
    {
        AD_AX_min = pA + AX * MinXD;
        AD_AX_max = pA + AX * MaxXD;
        botBox_be = AD_AX_min;
        topBox_be = AD_AX_max;

        Bear = IIf( ( dHigh > AD_AX_min ) AND( dHigh < AD_AX_max )
                    AND( dLow >= pC ) AND( dHigh == H ),
                    True, False );
        Bear = Bear AND( dHigh > pB );
    }

    if( showDotsAtD )
        PlotShapes( IIf( Bear, shapeSmallCircle, Null ), ColorRGB( 128, 64, 64 ), 0, H, 20 );
}

function calculateBullishABCDPattern( MinAC, MaxAC, MinBD, MaxBD )
{
    Bull4 = PTvalid_bu AND( BC_AB_bu > MinAC ) AND( BC_AB_bu < MaxAC );

    dHigh = HighestSince( Bull4, H );
    dLow = LowestSince( Bull4, L );

    pC = ValueWhen( Bull4, P1H1 );
    pB = ValueWhen( Bull4, V1L1 );
    pA = ValueWhen( Bull4, P1H2 );
    pX = ValueWhen( Bull4, V1L2 );
    CB = pC - pB;

    CD_BC_min = pC - CB * MinBD;
    CD_BC_max = pC - CB * MaxBD;

    Bull = IIf( ( dLow < CD_BC_min ) AND( dLow > CD_BC_max )
                AND( dHigh <= pC ) AND( dLow == L ),
                True, False );
    Bull = Bull AND( dLow < pB );

    if( showDotsAtD )
        PlotShapes( IIf( Bull, shapeSmallCircle, Null ), ColorRGB( 64, 128, 64 ), 0, L, -20 );
}

function calculateBearishABCDPattern( MinAC, MaxAC, MinBD, MaxBD )
{
    Bear4 = PTvalid_be AND( BC_AB_be > MinAC ) AND( BC_AB_be < MaxAC );

    dHigh = HighestSince( Bear4, H );
    dLow = LowestSince( Bear4, L );

    pA = ValueWhen( Bear4, V1L2 );
    pB = ValueWhen( Bear4, P1H1 );
    pC = ValueWhen( Bear4, V1L1 );
    CB = pB - pC;

    CD_BC_min = pC + CB * MinBD;
    CD_BC_max = pC + CB * MaxBD;

    Bear = IIf( ( dHigh > CD_BC_min ) AND( dHigh < CD_BC_max )
                AND( dLow >= pC ) AND( dHigh == H ),
                True, False );
    Bear = Bear AND( dHigh > pB );

    if( showDotsAtD )
        PlotShapes( IIf( Bear, shapeSmallCircle, Null ), ColorRGB( 128, 128, 64 ), 0, H, 20 );
}

function showBullishHarmonicPattern( patternName )
{
    BullHar4 = Bull4;
    BullHar = Bull;
    rBullHar4 = Reverse( BullHar4, 0, lvb );
    rBullHar = Reverse( BullHar, 0, lvb );
    rBullHar = ExRem( rBullHar, rBullHar4 );
    BullHar = Reverse( rBullHar, 0, lvb );
    X = ValueWhen( BullHar4, V1L2 );
    Xbar = ValueWhen( BullHar4, V1Bar2 );
    A = ValueWhen( BullHar4, P1H2 );
    Abar = ValueWhen( BullHar4, P1bar2 );
    B = ValueWhen( BullHar4, V1L1 );
    Bbar = ValueWhen( BullHar4, V1bar1 );
    C1 = ValueWhen( BullHar4, P1H1 );
    C1bar = ValueWhen( BullHar4, P1bar1 );
    D = ValueWhen( BullHar, L );
    Dbar = ValueWhen( BullHar, bi );
    ABdXA = SafeDivide( A - B, A - X );
    BCdAB = SafeDivide( C1 - B, A - B );
    ADdXA = SafeDivide( A - D, A - X );
    BCdCD = SafeDivide( C1 - D, C1 - B );

    for( i = lvb; i > fvb; i-- )
    {
        if( BullHar[i] )
        {
            drawHarmonicPattern( Xbar[i], X[i], Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i],
                                 D[i], ABdXA[i], BCdAB[i], ADdXA[i], BCdCD[i], topBox_bu[i], botBox_bu[i],
                                 patternName, ColorRGB( 0, 0, 255 ), ColorRGB( 0, 0, 120 ), ColorRGB( 0, 0, 30 ), -2, 1 );
        }
    }
}

function showBearishHarmonicPattern( patternName )
{
    BearHar4 = Bear4;
    BearHar = Bear;
    rBearHar4 = Reverse( BearHar4, 0, lvb );
    rBearHar = Reverse( BearHar, 0, lvb );
    rBearHar = ExRem( rBearHar, rBearHar4 );
    BearHar = Reverse( rBearHar, 0, lvb );
    X = ValueWhen( BearHar4, P1H2 );
    Xbar = ValueWhen( BearHar4, P1Bar2 );
    A = ValueWhen( BearHar4, V1L2 );
    Abar = ValueWhen( BearHar4, V1bar2 );
    B = ValueWhen( BearHar4, P1H1 );
    Bbar = ValueWhen( BearHar4, P1bar1 );
    C1 = ValueWhen( BearHar4, V1L1 );
    C1bar = ValueWhen( BearHar4, V1bar1 );
    D = ValueWhen( BearHar, H );
    Dbar = ValueWhen( BearHar, bi );
    ABdXA = SafeDivide( B - A, X - A );
    BCdAB = SafeDivide( B - C1, B - A );
    ADdXA = SafeDivide( D - A, X - A );
    BCdCD = SafeDivide( D - C1, B - C1 );

    for( i = lvb; i > fvb; i-- )
    {
        bearcolor = colorRed;
        linethick = 1;

        if( BearHar[i] )
        {
            drawHarmonicPattern( Xbar[i], X[i], Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i],
                                 D[i], ABdXA[i], BCdAB[i], ADdXA[i], BCdCD[i], topBox_be[i], botBox_be[i],
                                 patternName, ColorRGB( 255, 0, 0 ), ColorRGB( 120, 0, 0 ), ColorRGB( 30, 0, 0 ), 1, -1 );
        }
    }
}

function showBullishABCDPattern( patternName )
{
    BullHar4 = Bull4;
    BullHar = Bull;
    rBullHar4 = Reverse( BullHar4, 0, lvb );
    rBullHar = Reverse( BullHar, 0, lvb );
    rBullHar = ExRem( rBullHar, rBullHar4 );
    BullHar = Reverse( rBullHar, 0, lvb );
    A = ValueWhen( BullHar4, P1H2 );
    Abar = ValueWhen( BullHar4, P1bar2 );
    B = ValueWhen( BullHar4, V1L1 );
    Bbar = ValueWhen( BullHar4, V1bar1 );
    C1 = ValueWhen( BullHar4, P1H1 );
    C1bar = ValueWhen( BullHar4, P1bar1 );
    D = ValueWhen( BullHar, L );
    Dbar = ValueWhen( BullHar, bi );
    BCdAB = SafeDivide( C1 - B, A - B );
    BCdCD = SafeDivide( C1 - D, C1 - B );

    for( i = lvb; i > fvb; i-- )
    {
        bullcolor = colorGreen;
        linethick = 1;

        if( BullHar[i] AND bu )
        {
            drawABCDPattern( Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i], D[i], BCdAB[i], BCdCD[i],
                             CD_BC_min[i], CD_BC_max[i], patternName, ColorGreen, ColorRGB( 0, 80, 0 ), ColorRGB( 0, 10, 0 ), 1, 1 );
        }
    }
}

function showBearishABCDPattern( patternName )
{
    BearHar4 = Bear4;
    BearHar = Bear;
    rBearHar4 = Reverse( BearHar4, 0, lvb );
    rBearHar = Reverse( BearHar, 0, lvb );
    rBearHar = ExRem( rBearHar, rBearHar4 );
    BearHar = Reverse( rBearHar, 0, lvb );
    A = ValueWhen( BearHar4, V1L2 );
    Abar = ValueWhen( BearHar4, V1bar2 );
    B = ValueWhen( BearHar4, P1H1 );
    Bbar = ValueWhen( BearHar4, P1bar1 );
    C1 = ValueWhen( BearHar4, V1L1 );
    C1bar = ValueWhen( BearHar4, V1bar1 );
    D = ValueWhen( BearHar, H );
    Dbar = ValueWhen( BearHar, bi );
    BCdAB = SafeDivide( B - C1, B - A );
    BCdCD = SafeDivide( D - C1, B - C1 );

    for( i = lvb; i > fvb; i-- )
    {
        bearcolor = colorYellow;
        linethick = 1;

        if( BearHar[i] AND be )
        {
            drawABCDPattern( Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i], D[i], BCdAB[i], BCdCD[i],
                             CD_BC_min[i], CD_BC_max[i], patternName, ColorYellow, ColorRGB( 80, 80, 0 ), ColorRGB( 10, 10, 0 ), -2, -1 );
        }
    }
}

// DISPLAY
SetChartOptions( 0, chartShowArrows | chartShowDates );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );
Plot( C, "", colorWhite, styleCandle, Null, Null, 0, 1 );

if( bu )
{
    if( showGartley )
    {
        // Bullish Gartley Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Gartley_MinXB, Gartley_MaxXB, Gartley_MinAC, Gartley_MaxAC, Gartley_MinXD, Gartley_MaxXD, Gartley_MinBD, Gartley_MaxBD );
        showBullishHarmonicPattern( "Bullish Gartley" );
        BullGartley = Bull;
    }

    if( showBat )
    {
        // Bullish Bat Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Bat_MinXB, Bat_MaxXB, Bat_MinAC, Bat_MaxAC, Bat_MinXD, Bat_MaxXD, Bat_MinBD, Bat_MaxBD );
        showBullishHarmonicPattern( "Bullish Bat" );
        BullBat = Bull;
    }

    if( showAlternateBat )
    {
        // Bullish Alternate Bat Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( AlternateBat_MinXB, AlternateBat_MaxXB, AlternateBat_MinAC, AlternateBat_MaxAC, AlternateBat_MinXD, AlternateBat_MaxXD, AlternateBat_MinBD, AlternateBat_MaxBD );
        showBullishHarmonicPattern( "Bullish Alternate Bat" );
        BullAlternateBat = Bull;
    }

    if( showButterfly )
    {
        // Bullish Butterfly Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Butterfly_MinXB, Butterfly_MaxXB, Butterfly_MinAC, Butterfly_MaxAC, Butterfly_MinXD, Butterfly_MaxXD, Butterfly_MinBD, Butterfly_MaxBD );
        showBullishHarmonicPattern( "Bullish Butterfly" );
        BullButterfly = Bull;
    }

    if( showCrab )
    {
        // Bullish Crab Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Crab_MinXB, Crab_MaxXB, Crab_MinAC, Crab_MaxAC, Crab_MinXD, Crab_MaxXD, Crab_MinBD, Crab_MaxBD );
        showBullishHarmonicPattern( "Bullish Crab" );
        BullCrab = Bull;
    }

    if( showDeepCrab )
    {
        // Bullish DeepCrab Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( DeepCrab_MinXB, DeepCrab_MaxXB, DeepCrab_MinAC, DeepCrab_MaxAC, DeepCrab_MinXD, DeepCrab_MaxXD, DeepCrab_MinBD, DeepCrab_MaxBD );
        showBullishHarmonicPattern( "Bullish Deep Crab" );
        BullDeepCrab = Bull;
    }

    if( showCypher )
    {
        // Bullish Cypher Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Cypher_MinXB, Cypher_MaxXB, Cypher_MinAC, Cypher_MaxAC, Cypher_MinXD, Cypher_MaxXD, Cypher_MinBD, Cypher_MaxBD );
        showBullishHarmonicPattern( "Bullish Cypher" );
        BullCypher = Bull;
    }

    if( showABCD )
    {
        // Bullish ABCD Pattern
        Bull = Bull4 = 0;
        CD_BC_min = CD_BC_max = 0;
        calculateBullishABCDPattern( ABCD_MinAC, ABCD_MaxAC, ABCD_MinBD, ABCD_MaxBD );
        showBullishABCDPattern( "Bullish ABCD" );
        BullABCD = Bull;
    }
}

if( be )
{
    if( showGartley )
    {
        // Bearish Gartley Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Gartley_MinXB, Gartley_MaxXB, Gartley_MinAC, Gartley_MaxAC, Gartley_MinXD, Gartley_MaxXD, Gartley_MinBD, Gartley_MaxBD );
        showBearishHarmonicPattern( "Bearish Gartley" );
        BearGartley = Bear;
    }

    if( showBat )
    {
        // Bearish Bat Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Bat_MinXB, Bat_MaxXB, Bat_MinAC, Bat_MaxAC, Bat_MinXD, Bat_MaxXD, Bat_MinBD, Bat_MaxBD );
        showBearishHarmonicPattern( "Bearish Bat" );
        BearBat = Bear;
    }

    if( showAlternateBat )
    {
        // Bearish Alternate Bat Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( AlternateBat_MinXB, AlternateBat_MaxXB, AlternateBat_MinAC, AlternateBat_MaxAC, AlternateBat_MinXD, AlternateBat_MaxXD, AlternateBat_MinBD, AlternateBat_MaxBD );
        showBearishHarmonicPattern( "Bearish Alternate Bat" );
        BearAlternateBat = Bear;
    }

    if( showButterfly )
    {
        // Bearish Butterfly Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Butterfly_MinXB, Butterfly_MaxXB, Butterfly_MinAC, Butterfly_MaxAC, Butterfly_MinXD, Butterfly_MaxXD, Butterfly_MinBD, Butterfly_MaxBD );
        showBearishHarmonicPattern( "Bearish Butterfly" );
        BearButterfly = Bear;
    }

    if( showCrab )
    {
        // Bearish Crab Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Crab_MinXB, Crab_MaxXB, Crab_MinAC, Crab_MaxAC, Crab_MinXD, Crab_MaxXD, Crab_MinBD, Crab_MaxBD );
        showBearishHarmonicPattern( "Bearish Crab" );
        BearCrab = Bear;
    }

    if( showDeepCrab )
    {
        // Bearish Deep Crab Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( DeepCrab_MinXB, DeepCrab_MaxXB, DeepCrab_MinAC, DeepCrab_MaxAC, DeepCrab_MinXD, DeepCrab_MaxXD, DeepCrab_MinBD, DeepCrab_MaxBD );
        showBearishHarmonicPattern( "Bearish Deep Crab" );
        BearDeepCrab = Bear;
    }

    if( showCypher )
    {
        // Bearish Cypher Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Cypher_MinXB, Cypher_MaxXB, Cypher_MinAC, Cypher_MaxAC, Cypher_MinXD, Cypher_MaxXD, Cypher_MinBD, Cypher_MaxBD );
        showBearishHarmonicPattern( "Bearish Cypher" );
        BearCypher = Bear;
    }

    if( showABCD )
    {
        // Bearish ABCD Pattern
        Bull = Bull4 = 0;
        CD_BC_min = CD_BC_max = 0;
        calculateBearishABCDPattern( ABCD_MinAC, ABCD_MaxAC, ABCD_MinBD, ABCD_MaxBD );
        showBearishABCDPattern( "Bearish ABCD" );
        BearABCD = Bear;
    }
}

if( PlotFractals )
{
    PlotShapes( shapeSmallCircle * P1, colorRed, 0, H, 10 );
    PlotShapes( shapeSmallCircle * V1, colorBlue, 0, L, -10 );
}

// EXPLORATION
if( Status( "action" ) == actionExplore )
{
    Filter = (
                 BullBat OR BearBat
                 OR BullGartley OR BearGartley
                 OR BullButterfly OR BearButterfly
                 OR BullCrab OR BearCrab
                 OR BullABCD OR BearABCD
                 OR BullAlternateBat OR BearAlternateBat
                 OR BullDeepCrab OR BearDeepCrab
                 OR BullCypher OR BearCypher );

    PatternDirection =
        IIf( BullGartley, 1,
             IIf( BearGartley, -1,
                  IIf( BullBat, 1,
                       IIf( BearBat, -1,
                            IIf( BullButterfly, 1,
                                 IIf( BearButterfly, -1,
                                      IIf( BullCrab, 1,
                                           IIf( BearCrab, -1,
                                                   IIf( BullABCD, 1,
                                                           IIf( BearABCD, -1,
                                                                   IIf( BullAlternateBat, 1,
                                                                           IIf( BearAlternateBat, -1,
                                                                                   IIf( BullDeepCrab, 1,
                                                                                           IIf( BearDeepCrab, -1,
                                                                                                   IIf( BullCypher, 1,
                                                                                                           IIf( BearCypher, -1 , 0 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) );
    TextColor = IIf( patternDirection > 0, ColorRGB( 0, 255, 0 ), ColorRGB( 255, 0, 0 ) );
    PatternValue =
        IIf( BullGartley, 1,
             IIf( BearGartley, 2,
                  IIf( BullBat, 3,
                       IIf( BearBat, 4,
                            IIf( BullButterfly, 5,
                                 IIf( BearButterfly, 6,
                                      IIf( BullCrab, 7,
                                           IIf( BearCrab, 8,
                                                   IIf( BullABCD, 9,
                                                           IIf( BearABCD, 10,
                                                                   IIf( BullAlternateBat, 11,
                                                                           IIf( BearAlternateBat, 12,
                                                                                   IIf( BullDeepCrab, 13,
                                                                                           IIf( BearDeepCrab, 14,
                                                                                                   IIf( BullCypher, 15,
                                                                                                           IIf( BearCypher, 16 , 0 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) );

    PatternList = "None\nBullish Gartley\nBearish Gartley" +
                  "\nBullish Bat\nBearish Bat" +
                  "\nBullish Butterfly\nBearish Butterfly" +
                  "\nBullish Crab\nBearish Crab" +
                  "\nBullish ABCD\nBearish ABCD" +
                  "\nBullish Alternate Bat\nBearish Alternate Bat" +
                  "\nBullish Deep Crab\nBearish Deep Crab" +
                  "\nBullish Cyper\nBearish Cypher";


    AddMultiTextColumn( PatternValue, PatternList, "Pattern Name", 1.0, TextColor, colorWhite, 125 ); // version 6.2 and Higher
}

_SECTION_END();
13 Likes

I have added three more patterns to this and appear to be working fine, I tried to post the same in Reply to one of your posts where you had modernized the AFL, but it threw up an error that it had utilized more than the required lines. I wanted to thank you personally for the nice AFL u had re created and improvised it. Thank you Sir.

ok thanks. Maybe you can post your additional patterns separately.

I also added some things to the code. But wanted to post later because I am still working on a little issue. Or I am revisiting these "clean" pivots again since the original code is not perfect. But the original code (that is currently in the code) is pretty good, almost perfect.

this is 1 change i made. I just use this instead of the Ref( bi, -1 ) stuff

bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

I also added 1 pattern , the reciprocal ABCD. All the patterns do not have completed definitions yet. For instance there is not time constraint built in yet. So if you have suggestions let me know.

3 Likes

also if someone is using the "explore" function that gives an error because I use the Reverse function. Not sure why this is but to avoid the error the reverse function needs to be put inside "if" statement like:

    if( lvb > 0 )
    {
        rBullHar4 = Reverse( BullHar4, 0, lvb );
        rBullHar = Reverse( BullHar, 0, lvb );
        rBullHar = ExRem( rBullHar, rBullHar4 );
        BullHar = Reverse( rBullHar, 0, lvb );
    }

The error itself is:

Error 52. Invalid argument values for Reverse() function. The function expects that first < last MyFormulas\harmonics\hp9_fractals.afl 165 44

I will update the code some other time when I finish my version of the pivots. It seems these "fractal" pivots are the best suitable for these patterns. But if someone knows some other suitable pivots let me know. Scott Carney does not mention what he uses is any of his 3 books as far as I can see.

2 Likes

Reverse() function requires version 5.90 or higher. It will produce error if somebody tries ancient version.

It is good practice to include

Version( 6.00 ); // change to reflect minimum required version for the formula

in formulas posted on the forum, because it will directly tell the user they are using version TOO OLD for given formula.

i was asked for the latest version via PM. I did not post yet because the pivots are still not perfect but the version below is better. If someone knows the correct pivots to use for this let me know. I mostly not really use it just the ABCD patterns I like.

About the exploration. In the code below I use a version that scans all patterns but in the "Explore" setting you have to set it to look for just the last bar.

I could not post the code because it exceeds 40000 characters. So maybe the threshold can be increased to 45000, else PM me with an email address where I can send the code.

It is 50000 characters now.

2 Likes
_SECTION_BEGIN( "Harmonic patterns" );
//Version( 6.20 );
/*
ratio labels
AB_AX means the ratio (A-B)/(A-X). It is the retracement of A to B over the price range A to X
BC_AB means the ratio (C-B)/(A-B)
CD_BC means the ratio (C-D)/(C-B)
AD_AX means the ratio (A-D)/(A-X)
https://www.linkedin.com/pulse/powerful-harmonic-patterns-simplified-varun-aggarwal
*/

//TF = Interval( 1 );
//StaticVarSet( "~ChartTF_db" + Name(), TF );
GfxSetZOrder( -5 );
GfxSetCoordsMode( 1 );

bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

// PARAMETERS
rightstrength = Param( "Right Strength", 5, 2, 50, 1 );
leftstrength = Param( "Left Strength", 10, 2, 50, 1 );
bu = ParamToggle( "Bullish Pattern", "Off|On", 1 );
be = ParamToggle( "Bearish Pattern", "Off|On", 1 );
showABCD = ParamToggle( "Show ABCD", "Off|On", 1 );
showReciprocalABCD = ParamToggle( "Show Reciprocal ABCD", "Off|On", 0 );
showGartley = ParamToggle( "Show Gartley", "Off|On", 0 );
showBat = ParamToggle( "Show Bat", "Off|On", 0 );
showAlternateBat = ParamToggle( "Show Alternate Bat", "Off|On", 0 );
showButterfly = ParamToggle( "Show Butterfly", "Off|On", 0 );
showCrab = ParamToggle( "Show Crab", "Off|On", 0 );
showDeepCrab = ParamToggle( "Show Deep Crab", "Off|On", 0 );
showCypher = ParamToggle( "Show Cypher", "Off|On", 0 );
ft = ParamList( "Font Type", "Tahoma|Arial Black|Verdana|Courier New|Times New Roman|Open Sans|Segoe UI|DejaVu Sans", 6 );
sz = Param( "Font Size", 15, 8, 50, 1 );
st = Param( "Separation of Letters", 3, 1, 10, 1 );
dl = Param( "Dashed Line Number", 2, 1, 4, 1 );
showDotsAtD = ParamToggle( "Show Dots at D", "Off|On", 1 );
showPatternName = ParamToggle( "Show Pattern Name", "Off|On", 1 );
loc = Param( "Pattern Name Position", 6, 1, 10, 0.1 );
plotFractals = ParamToggle( "Plot Fractal Pivot Points", "Off|On", 1 );
ps = ParamToggle( "Swing D constraint", "use only AD_AX contraint|use both AD_AX AND CB_BC constraint", 1 );
deviation = Param( "Deviation", 10, 0.1, 100, 0.1 );
showZigZag = ParamToggle( "Show Zig Zag", "Off|On", 1 );
fillPRZ = ParamToggle( "Fill PRZ area with color", "Off|On", 1 );

// Gartley
Gartley_MinXB = 0.618 - 0.618 * deviation / 100; // retrace from A to B over distance X to A
Gartley_MaxXB = 0.618 + 0.618 * deviation / 100;
Gartley_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Gartley_MaxAC = 0.886 + 0.886 * deviation / 100;
Gartley_MinBD = 1.13 - 1.13 * deviation / 100; // retrace from C to D over distance B to C
Gartley_MaxBD = 1.618 + 1.618 * deviation / 100;
Gartley_MinXD = 0.786 - 0.786 * deviation / 100; // retrace from A to D over distance X to A
Gartley_MaxXD = 0.786 + 0.786 * deviation / 100;

// Bat
Bat_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Bat_MaxXB = 0.5 + 0.5 * deviation / 100;
Bat_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Bat_MaxAC = 0.886 + 0.886 * deviation / 100;
Bat_MinBD = 1.618 - 1.618 * deviation / 100; // retrace from C to D over distance B to C
Bat_MaxBD = 2.618 + 2.618 * deviation / 100;
Bat_MinXD = 0.886 - 0.886 * deviation / 100; // retrace from A to D over distance X to A
Bat_MaxXD = 0.886 + 0.886 * deviation / 100;

// Alternate Bat
AlternateBat_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
AlternateBat_MaxXB = 0.382 + 0.382 * deviation / 100;
AlternateBat_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
AlternateBat_MaxAC = 0.886 + 0.886 * deviation / 100;
AlternateBat_MinBD = 2.0 - 2.0 * deviation / 100; // retrace from C to D over distance B to C
AlternateBat_MaxBD = 3.618 + 3.618 * deviation / 100;
AlternateBat_MinXD = 1.13 - 1.13 * deviation / 100; // retrace from A to D over distance X to A
AlternateBat_MaxXD = 1.13 + 1.13 * deviation / 100;

// Butterfly
Butterfly_MinXB = 0.786 - 0.786 * deviation / 100; // retrace from A to B over distance X to A
Butterfly_MaxXB = 0.786 + 0.786 * deviation / 100;
Butterfly_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Butterfly_MaxAC = 0.886 + 0.886 * deviation / 100;
Butterfly_MinBD = 1.618 - 1.618 * deviation / 100; // retrace from C to D over distance B to C
Butterfly_MaxBD = 2.24 + 2.24 * deviation / 100;
Butterfly_MinXD = 1.27 - 1.27 * deviation / 100; // retrace from A to D over distance X to A
Butterfly_MaxXD = 1.27 + 1.27 * deviation / 100;

// Crab
Crab_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Crab_MaxXB = 0.618 + 0.618 * deviation / 100;
Crab_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
Crab_MaxAC = 0.886 + 0.886 * deviation / 100;
Crab_MinBD = 2.618 - 2.618 * deviation / 100; // retrace from C to D over distance B to C
Crab_MaxBD = 3.618 + 3.618 * deviation / 100;
Crab_MinXD = 1.618 - 1.618 * deviation / 100; // retrace from A to D over distance X to A
Crab_MaxXD = 1.618 + 1.618 * deviation / 100;

// Deep Crab
DeepCrab_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
DeepCrab_MaxXB = 0.618 + 0.618 * deviation / 100;
DeepCrab_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
DeepCrab_MaxAC = 0.886 + 0.886 * deviation / 100;
DeepCrab_MinBD = 2.618 - 2.618 * deviation / 100; // retrace from C to D over distance B to C
DeepCrab_MaxBD = 3.618 + 3.618 * deviation / 100;
DeepCrab_MinXD = 1.618 - 1.618 * deviation / 100; // retrace from A to D over distance X to A
DeepCrab_MaxXD = 1.618 + 1.618 * deviation / 100;

// Cypher
Cypher_MinXB = 0.382 - 0.382 * deviation / 100; // retrace from A to B over distance X to A
Cypher_MaxXB = 0.618 + 0.618 * deviation / 100;
Cypher_MinAC = 1.13 - 1.13 * deviation / 100; // retrace from B to C over distance A to B
Cypher_MaxAC = 1.414 + 1.414 * deviation / 100;
Cypher_MinBD = 1.272 - 1.272 * deviation / 100; // retrace from C to D over distance B to C
Cypher_MaxBD = 2.0 + 2.0 * deviation / 100;
Cypher_MinXD = 0.786 - 0.786 * deviation / 100; // retrace from A to D over distance X to A
Cypher_MaxXD = 0.786 + 0.786 * deviation / 100;

// ABCD
ABCD_MinAC = 0.382 - 0.382 * deviation / 100; // retrace from B to C over distance A to B
ABCD_MaxAC = 0.886 + 0.886 * deviation / 100;
ABCD_MinBD = 1.13 - 1.13 * deviation / 100; // retrace from C to D over distance B to C
ABCD_MaxBD = 2.618 + 2.618 * deviation / 100;

// Reciprocal ABCD
ReciprocalABCD_MinAC = 1.13 - 1.13 * deviation / 100; // retrace from B to C over distance A to B
ReciprocalABCD_MaxAC = 3.618 + 3.618 * deviation / 100;
ReciprocalABCD_MinBD = 0.382 - 0.382 * deviation / 100; // retrace from C to D over distance B to C
ReciprocalABCD_MaxBD = 0.886 + 0.886 * deviation / 100;

// DECLARE GLOBAL ARRAYS
Bull = Bull4 = Bear = Bear4 = 0;
AD_AX_min = AD_AX_max = 0;
CD_BC_min = CD_BC_max = 0;
BullBat = BearBat = BullGartley = BearGartley = BullButterfly = BearButterfly = BullCrab = BearCrab = BullABCD = BearABCD = 0;
BullAlternateBat = BearAlternateBat = BullDeepCrab = BearDeepCrab = BullCypher = BearCypher = 0;
topBox_bu = topBox_be = botBox_bu = botBox_be = 0;
pk = tr = 0;
zigzag = prch = prcl = Null;

// CALCULATE THE PIVOTS
pk = H > Ref( HHV( H, leftstrength ), -1 ) AND Ref( HHV( H, rightstrength ), rightstrength ) <= H;
tr = L < Ref( LLV( L, leftstrength ), -1 ) AND Ref( LLV( L, rightstrength ), rightstrength ) >= L;
//pk = H > Ref( HHV( H, leftstrength ), -1 );
//tr = L < Ref( LLV( L, leftstrength ), -1 );

// 'clean' the pivots function
// meaning make the pivots alternate like pk-tr-pk-tr-pk-tr-etc..
procedure alternate_proc( pk, tr )
{
    global pkg;
    global trg;

    // alternate pivots
    pkg = pk;
    trg = tr;
    pkHigh = 0;
    pkHighIndex = 0;
    trLow = 1e10;
    trLowIndex = 0;

    for( i = fvb; i <= lvb; i++ )
    {
        // peak and trough on same bar
        if( pk[i] AND tr[i] )
        {
            if( pkHighIndex > trLowIndex )
            {
                pkg[i] = 0;
                trg[i] = 1;

                if( L[i] <= trLow )
                {
                    pkHigh = 0;
                    pkHighIndex = 0;
                    trLow = L[i];
                    trLowIndex = i;
                }
                else
                {
                    pkHigh = 0;
                    pkHighIndex = 0;
                }
            }
            else
                if( pkHighIndex < trLowIndex )
                {
                    pkg[i] = 1;
                    trg[i] = 0;

                    if( H[i] >= pkHigh )
                    {
                        trLow = 1e10;
                        trLowIndex = 0;
                        pkHigh = H[i];
                        pkHighIndex = i;
                    }
                    else
                    {
                        trLow = 1e10;
                        trLowIndex = 0;
                    }
                }
                else
                {
                    pkg[i] = 0;
                    trg[i] = 0;
                }
        }
        else
            // consecutive higher peak found
            if( pk[i] AND H[i] >= pkHigh )
            {
                // disable the previous lower peak
                pkg[pkHighIndex] = 0;
                // update new peak variables
                pkHigh = H[i];
                pkHighIndex = i;
                // reset trough variables
                trLow = 1e10;
                trLowIndex = 0;
            }
            else
                // consecutive lower peak found
                if( pk[i] AND H[i] < pkHigh )
                {
                    // disable this peak
                    pkg[i] = 0;
                    // reset trough variables
                    trLow = 1e10;
                    trLowIndex = 0;
                }
                else
                    // consecutive lower trough found
                    if( tr[i] AND L[i] <= trLow )
                    {
                        // disable the previous higher trough
                        trg[trLowIndex] = 0;
                        // update trough variables
                        trLow = L[i];
                        trLowIndex = i;
                        // reset peak variables
                        pkHigh = 0;
                        pkHighIndex = 0;
                    }
                    else
						// consecutive higher trough found
                        if( tr[i] AND L[i] > trLow )
                        {
                            // disable this trough
                            trg[i] = 0;
                            // reset peak variables
                            pkHigh = 0;
                            pkHighIndex = 0;
                        }
    }
}

// run clean pivots
alternate_proc( pk, tr );
pk = pkg;
tr = trg;

// BULLISH AND BEARISH PATTERN PREPARATIONS
pkH1 = ValueWhen( pk, H );
pkBar1 = ValueWhen( pk, bi );
pkH2 = ValueWhen( pk, H, 2 );
pkBar2 = ValueWhen( pk, bi, 2 );
trL1 = ValueWhen( tr, L );
trBar1 = ValueWhen( tr, bi );
trL2 = ValueWhen( tr, L, 2 );
trBar2 = ValueWhen( tr, bi, 2 );

PTvalid_bu = ( pkBar1 > trBar1 AND trBar1 > pkBar2 AND pkbar2 > trBar2 ) AND pk;

AX_bu = pkH2 - trL2;
AB_bu = pkH2 - trL1;
BC_bu = pkH1 - trL1;

AB_AX_bu = SafeDivide( AB_bu, AX_bu );
BC_AB_bu = SafeDivide( BC_bu, AB_bu );

PTvalid_be = ( trBar1 > pkBar1 AND pkBar1 > trBar2 AND trBar2 > pkBar2 ) AND tr;

AX_be = pkH2 - trL2;
AB_be = pkH1 - trL2;
BC_be = pkH1 - trL1;

AB_AX_be = SafeDivide( AB_be, AX_be );
BC_AB_be = SafeDivide( BC_be, AB_be );

// PATTERN CALCULATION AND DISPLAY FUNCTIONS
function calculateZigZag()
{
    zigup = Flip( tr, pk );
    zigupLow = ValueWhen( tr, prcl, 1 );
    zigupHigh = ValueWhen( pk, prch, 0 );
    zigupLowIndex = ValueWhen( tr, bi, 1 );
    zigupHighIndex = ValueWhen( pk, bi, 0 );
    slopeup = IIf( zigup, ( zigupHigh - zigupLow ) / ( zigupHighIndex - zigupLowIndex ) , Null );
    zigupLine = IIf( zigup, zigupLow + slopeup * BarsSince( tr ), Null );

    zigdn = Flip( pk, tr );
    zigdnLow = ValueWhen( tr, prcl, 0 );
    zigdnHigh = ValueWhen( pk, prch, 1 );
    zigdnLowIndex = ValueWhen( tr, bi, 0 );
    zigdnHighIndex = ValueWhen( pk, bi, 1 );
    slopedn = IIf( zigdn, ( zigdnLow - zigdnHigh ) / ( zigdnLowIndex - zigdnHighIndex ) , Null );
    zigdnLine = IIf( zigdn, zigdnHigh + slopedn * BarsSince( pk ), Null );

    ZigZag = IIf( zigup, zigupLine, IIf( zigdn, zigdnLine, Null ) );
    ZigZag = IIf( bi > Max( LastValue( ValueWhen( tr, bi ) ), LastValue( ValueWhen( pk, bi ) ) ), Null, ZigZag );
}

function calculateLastSegments()
{
    lastidxpk = LastValue( ValueWhen( pk, bi ) );
    lastidxtr = LastValue( ValueWhen( tr, bi ) );
    lastvalpk = LastValue( ValueWhen( pk, prch ) );
    lastvaltr = LastValue( ValueWhen( tr, prcl ) );
    valpk = LastValue( HighestSince( Ref( tr, -1 ), prch , 1 ) );
    idxpk = LastValue( ValueWhen( prch == valpk, bi ) );
    valtr = LastValue( LowestSince( Ref( pk, -1 ), prcl, 1 ) );
    idxtr = LastValue( ValueWhen( prcl == valtr, bi ) );

    if( lastidxpk > lastidxtr )
    {
        x0 = lastidxpk;
        y0 = lastvalpk;
        x1 = idxtr;
        y1 = valtr;
        line1 = linedn = LineArray( x0, y0, x1, y1 );
        tr[idxtr] = 1;
        valpk = LastValue( HighestSince( Ref( tr, -1 ), prch, 1 ) );
        idxpk = LastValue( ValueWhen( prch == valpk, bi ) );
    }

    if( lastidxpk < lastidxtr )
    {
        x0 = lastidxtr;
        y0 = lastvaltr;
        x1 = idxpk;
        y1 = valpk;
        line1 = lineup = LineArray( x0, y0, x1, y1 );
        pk[idxpk] = 1;
        valtr = LastValue( LowestSince( Ref( pk, -1 ), prcl, 1 ) );
        idxtr = LastValue( ValueWhen( prcl == valtr, bi ) );
    }

    ZigZag = IIf( !IsEmpty( line1 ), line1, ZigZag );
}

function GfxConvertBarToPixelX( bar )
{
    local fvb1, lvb1;

    lvb1 = Status( "lastvisiblebar" );
    fvb1 = Status( "firstvisiblebar" );
    pxchartleft = Status( "pxchartleft" );
    pxchartwidth = Status( "pxchartwidth" );

    return pxchartleft + bar  * pxchartwidth / ( lvb1 - fvb1 + 1 );
}

function GfxConvertValueToPixelY( Value )
{
    local Miny, Maxy, pxchartbottom, pxchartheight;

    Miny = Status( "axisminy" );
    Maxy = Status( "axismaxy" );

    pxchartbottom = Status( "pxchartbottom" );
    pxchartheight = Status( "pxchartheight" );

    return pxchartbottom - floor( 0.5 + ( Value - Miny ) * SafeDivide( pxchartheight, Maxy - Miny ) );
}

function CalculateAngle( x1, y1, x2, y2 )
{
    // calculate angle of text
    x1 = GfxConvertBarToPixelX( x1 );
    y1 = GfxConvertValueToPixelY( y1 );
    x2 = GfxConvertBarToPixelX( x2 );
    y2 = GfxConvertValueToPixelY( y2 );
    onerad = 57.2957795;
    angle = 10 * onerad * atan( SafeDivide( y2 - y1,  x2 - x1 ) ) * -1;
    return angle;
}

function drawHarmonicPattern( Xbar, X, Abar, A, Bbar, B, C1bar, C1, Dbar, D, ABdXA, BCdAB, ADdXA, BCdCD, topBox, botBox, patternName, clr1, clr2, clr3, fac, dir )
{
    GfxSetZOrder( -2 );
    GfxSelectPen( clr1, 2, 0 );
    GfxMoveTo( Xbar, X );
    GfxLineTo( Abar, A );
    GfxLineTo( Bbar, B );
    GfxLineTo( C1bar, C1 );
    GfxLineTo( Dbar, D );
    GfxSelectPen( clr1, 1, dl );
    GfxMoveTo( Abar, A );
    GfxLineTo( C1bar, C1 );
    GfxMoveTo( Xbar, X );
    GfxLineTo( Bbar, B );
    GfxLineTo( Dbar, D );
    GfxLineTo( Xbar, X );

    PlotTextSetFont( NumToStr( ABdXA, 1.2 ), ft, sz, ( Bbar + Xbar ) / 2, ( B + X ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdAB, 1.2 ), ft, sz, ( C1bar + Abar ) / 2, ( C1 + A ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( ADdXA, 1.2 ), ft, sz, ( Dbar + Xbar ) / 2, ( D + X ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdCD, 1.2 ), ft, sz, ( Bbar + Dbar ) / 2, ( B + D ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( "X", ft, sz, Xbar - st, X, clr1, colorDefault, 0 );
    PlotTextSetFont( "A", ft, sz, Abar - st, A, clr1, colorDefault, 0 );
    PlotTextSetFont( "B", ft, sz, Bbar - st, B, clr1, colorDefault, 0 );
    PlotTextSetFont( "C", ft, sz, C1bar + st, C1, clr1, colorDefault, 0 );
    PlotTextSetFont( "D", ft, sz, Dbar + st, D, clr1, colorDefault, 0 );

    if( showPatternName )
    {
        //PlotTextSetFont( "" + patternName, ft, sz, Xbar + 5, X, clr1, colorDefault, -1 * sz * fac );
        angle = calculateAngle( XBar, X, DBar, D );
        GfxSelectFont( ft, sz, 400, False, False, angle );
        GfxSetCoordsMode( 1 );
        GfxSetTextColor( clr1 );
        GfxTextOut( "" + patternName, Xbar + ( Dbar - Xbar ) / loc, X + ( D - X ) / loc );
    }

    // draw PRZ rectangle
    GfxSetZOrder( -3 );
    GfxSelectSolidBrush( clr3 );
    x0 = C1bar;
    y0 = topBox;
    x1 = Dbar;
    y1 = botBox;

    if( fillPRZ )
    {
        GfxSelectPen( clr2, 1, 0 );
        GfxRectangle( x0, y0, x1, y1 );
    }
    else
    {
        GfxSelectPen( clr2, 1, 0 );
        GfxMoveTo( x0, y0 );
        GfxLineTo( x0, y1 );
        GfxLineTo( x1, y1 );
        GfxLineTo( x1, y0 );
        GfxLineTo( x0, y0 );
    }
}

function drawABCDPattern( Abar, A, Bbar, B, C1bar, C1, Dbar, D, BCdAB, BCdCD, topBox, botBox, patternName, clr1, clr2, clr3, fac, dir )
{
    GfxSetZOrder( -1 );
    GfxSelectPen( clr1, 2, 0 );
    GfxMoveTo( Abar, A );
    GfxLineTo( Bbar, B );
    GfxLineTo( C1bar, C1 );
    GfxLineTo( Dbar, D );
    GfxSelectPen( clr1, 1, dl );
    GfxMoveTo( Abar, A );
    GfxLineTo( C1bar, C1 );
    GfxMoveTo( Bbar, B );
    GfxLineTo( Dbar, D );

    PlotTextSetFont( NumToStr( BCdAB, 1.2 ), ft, sz, ( C1bar + Abar ) / 2, ( C1 + A ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( NumToStr( BCdCD, 1.2 ), ft, sz, ( Bbar + Dbar ) / 2, ( B + D ) / 2, clr1, colorDefault, 0 );
    PlotTextSetFont( "A", ft, sz, Abar - st, A, clr1, colorDefault, sz * dir );
    PlotTextSetFont( "B", ft, sz, Bbar - st, B, clr1, colorDefault, -sz * dir );
    PlotTextSetFont( "C", ft, sz, C1bar + st, C1, clr1, colorDefault, sz * dir );
    PlotTextSetFont( "D", ft, sz, Dbar + st, D, clr1, colorDefault, - sz * dir );

    if( showPatternName )
    {
        //PlotTextSetFont( "" + patternName, ft, sz, Abar, A, clr1, colorDefault, sz * fac );

        if( dir == 1 )
        {
            angle = calculateAngle( ABar, A, C1Bar, C1 );
            GfxSelectFont( ft, sz, 400, False, False, angle );
            GfxSetCoordsMode( 1 );
            GfxSetTextColor( clr1 );
            GfxTextOut( "" + patternName, Abar + ( C1bar - Abar ) / loc, A + ( C1 - A ) / loc );
        }

        if( dir == ( -1 ) )
        {
            angle = calculateAngle( BBar, B, DBar, D );
            GfxSelectFont( ft, sz, 400, False, False, angle );
            GfxSetCoordsMode( 1 );
            GfxSetTextColor( clr1 );
            GfxTextOut( "" + patternName, Bbar + ( Dbar - Bbar ) / loc, B + ( D - B ) / loc );
        }
    }

    // draw PRZ rectangle
    GfxSetZOrder( -4 );
    GfxSelectSolidBrush( clr3 );
    x0 = C1bar;
    y0 = topBox;
    x1 = Dbar;
    y1 = botBox;

    if( fillPRZ )
    {
        GfxSelectPen( clr2, 1, 0 );
        GfxRectangle( x0, y0, x1, y1 );
    }
    else
    {
        GfxSelectPen( clr2, 1, 0 );
        GfxMoveTo( x0, y0 );
        GfxLineTo( x0, y1 );
        GfxLineTo( x1, y1 );
        GfxLineTo( x1, y0 );
        GfxLineTo( x0, y0 );
    }
}

function calculateBullishHarmonicPattern( MinXB, MaxXB, MinAC, MaxAC, MinXD, MaxXD, MinBD, MaxBD )
{
    Bull4 = PTvalid_bu AND( AB_AX_bu > MinXB ) AND( AB_AX_bu < MaxXB )
            AND( BC_AB_bu > MinAC ) AND( BC_AB_bu < MaxAC );

    dHigh = HighestSince( Bull4, H );
    dLow = LowestSince( Bull4, L );

    pC = ValueWhen( Bull4, pkH1 );
    pB = ValueWhen( Bull4, trL1 );
    pA = ValueWhen( Bull4, pkH2 );
    pX = ValueWhen( Bull4, trL2 );
    AX = pA - pX;
    BC = pC - pB;

    if( ps )
    {
        AD_AX_min = pA - AX * MinXD;
        AD_AX_max = pA - AX * MaxXD;
        CD_BC_min = pC - BC * MinBD;
        CD_BC_max = pC - BC * MaxBD;
        topBox_bu = Min( AD_AX_min, CD_BC_min );
        botBox_bu = Max( AD_AX_max, CD_BC_max );

        Bull = IIf( ( dLow < AD_AX_min ) AND( dLow > AD_AX_max )
                    AND( dLow < CD_BC_min ) AND( dLow > CD_BC_max )
                    AND( dHigh <= pC ) AND( dLow == L ),
                    True, False );
        Bull = Bull AND( dLow < pB );
    }
    else
    {
        AD_AX_min = pA - AX * MinXD;
        AD_AX_max = pA - AX * MaxXD;
        topBox_bu = AD_AX_min;
        botBox_bu = AD_AX_max;

        Bull = IIf( ( dLow < AD_AX_min ) AND( dLow > AD_AX_max )
                    AND( dHigh <= pC ) AND( dLow == L ),
                    True, False );
        Bull = Bull AND( dLow < pB );
    }

    if( showDotsAtD )
        PlotShapes( IIf( Bull, shapeSmallCircle, Null ), ColorRGB( 64, 64, 128 ), 0, L, -20 );
}

function calculateBearishHarmonicPattern( MinXB, MaxXB, MinAC, MaxAC, MinXD, MaxXD, MinBD, MaxBD )
{
    Bear4 = PTvalid_be AND( AB_AX_be > MinXB ) AND( AB_AX_be < MaxXB )
            AND( BC_AB_be > MinAC ) AND( BC_AB_be < MaxAC );

    dHigh = HighestSince( Bear4, H );
    dLow = LowestSince( Bear4, L );

    pX = ValueWhen( Bear4, pkH2 );
    pB = ValueWhen( Bear4, pkH1 );
    pA = ValueWhen( Bear4, trL2 );
    pC = ValueWhen( Bear4, trL1 );
    AX = pX - pA;
    BC = pB - pC;

    if( ps )
    {
        AD_AX_min = pA + AX * MinXD;
        AD_AX_max = pA + AX * MaxXD;
        CD_BC_min = pC + BC * MinBD;
        CD_BC_max = pC + BC * MaxBD;
        botBox_be = Max( AD_AX_min, CD_BC_min );
        topBox_be = Min( AD_AX_max, CD_BC_max );

        Bear = IIf( ( dHigh > AD_AX_min ) AND( dHigh < AD_AX_max )
                    AND( dHigh > CD_BC_min ) AND( dHigh < CD_BC_max )
                    AND( dLow >= pC ) AND( dHigh == H ),
                    True, False );
        Bear = Bear AND( dHigh > pB );
    }
    else
    {
        AD_AX_min = pA + AX * MinXD;
        AD_AX_max = pA + AX * MaxXD;
        botBox_be = AD_AX_min;
        topBox_be = AD_AX_max;

        Bear = IIf( ( dHigh > AD_AX_min ) AND( dHigh < AD_AX_max )
                    AND( dLow >= pC ) AND( dHigh == H ),
                    True, False );
        Bear = Bear AND( dHigh > pB );
    }

    if( showDotsAtD )
        PlotShapes( IIf( Bear, shapeSmallCircle, Null ), ColorRGB( 128, 64, 64 ), 0, H, 20 );
}

function calculateBullishABCDPattern( MinAC, MaxAC, MinBD, MaxBD, pattername )
{
    Bull4 = PTvalid_bu AND( BC_AB_bu > MinAC ) AND( BC_AB_bu < MaxAC );

    dHigh = HighestSince( Bull4, H );
    dLow = LowestSince( Bull4, L );

    pC = ValueWhen( Bull4, pkH1 );
    pB = ValueWhen( Bull4, trL1 );
    pA = ValueWhen( Bull4, pkH2 );
    CB = pC - pB;

    CD_BC_min = pC - CB * MinBD;
    CD_BC_max = pC - CB * MaxBD;

    Bull = IIf( ( dLow < CD_BC_min ) AND( dLow > CD_BC_max )
                AND( dHigh <= pC ) AND( dLow == L ),
                True, False );

    if( pattername == "ABCD" )
        Bull = Bull AND( dLow < pB );

    if( showDotsAtD )
        PlotShapes( IIf( Bull, shapeSmallCircle, Null ), ColorRGB( 64, 128, 64 ), 0, L, -20 );
}

function calculateBearishABCDPattern( MinAC, MaxAC, MinBD, MaxBD, patternname )
{
    Bear4 = PTvalid_be AND( BC_AB_be > MinAC ) AND( BC_AB_be < MaxAC );

    dHigh = HighestSince( Bear4, H );
    dLow = LowestSince( Bear4, L );

    pA = ValueWhen( Bear4, trL2 );
    pB = ValueWhen( Bear4, pkH1 );
    pC = ValueWhen( Bear4, trL1 );
    CB = pB - pC;

    CD_BC_min = pC + CB * MinBD;
    CD_BC_max = pC + CB * MaxBD;

    Bear = IIf( ( dHigh > CD_BC_min ) AND( dHigh < CD_BC_max )
                AND( dLow >= pC ) AND( dHigh == H ),
                True, False );

    if( patternname == "ABCD" )
        Bear = Bear AND( dHigh > pB );

    if( showDotsAtD )
        PlotShapes( IIf( Bear, shapeSmallCircle, Null ), ColorRGB( 128, 128, 64 ), 0, H, 20 );
}

function showBullishHarmonicPattern( patternName )
{
    BullHar4 = Bull4;
    BullHar = Bull;

    if( lvb > 0 )
    {
        rBullHar4 = Reverse( BullHar4, 0, lvb );
        rBullHar = Reverse( BullHar, 0, lvb );
        rBullHar = ExRem( rBullHar, rBullHar4 );
        BullHar = Reverse( rBullHar, 0, lvb );
    }

    X = ValueWhen( BullHar4, trL2 );
    Xbar = ValueWhen( BullHar4, trBar2 );
    A = ValueWhen( BullHar4, pkH2 );
    Abar = ValueWhen( BullHar4, pkbar2 );
    B = ValueWhen( BullHar4, trL1 );
    Bbar = ValueWhen( BullHar4, trbar1 );
    C1 = ValueWhen( BullHar4, pkH1 );
    C1bar = ValueWhen( BullHar4, pkbar1 );
    D = ValueWhen( BullHar, L );
    Dbar = ValueWhen( BullHar, bi );
    ABdXA = SafeDivide( A - B, A - X );
    BCdAB = SafeDivide( C1 - B, A - B );
    ADdXA = SafeDivide( A - D, A - X );
    BCdCD = SafeDivide( C1 - D, C1 - B );

    for( i = lvb; i > fvb; i-- )
    {
        if( BullHar[i] )
        {
            drawHarmonicPattern( Xbar[i], X[i], Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i],
                                 D[i], ABdXA[i], BCdAB[i], ADdXA[i], BCdCD[i], topBox_bu[i], botBox_bu[i],
                                 patternName, ColorRGB( 0, 0, 255 ), ColorRGB( 0, 0, 120 ), ColorRGB( 0, 0, 30 ), -2, 1 );
        }
    }
}

function showBearishHarmonicPattern( patternName )
{
    BearHar4 = Bear4;
    BearHar = Bear;

    if( lvb > 0 )
    {
        rBearHar4 = Reverse( BearHar4, 0, lvb );
        rBearHar = Reverse( BearHar, 0, lvb );
        rBearHar = ExRem( rBearHar, rBearHar4 );
        BearHar = Reverse( rBearHar, 0, lvb );
    }

    X = ValueWhen( BearHar4, pkH2 );
    Xbar = ValueWhen( BearHar4, pkBar2 );
    A = ValueWhen( BearHar4, trL2 );
    Abar = ValueWhen( BearHar4, trbar2 );
    B = ValueWhen( BearHar4, pkH1 );
    Bbar = ValueWhen( BearHar4, pkbar1 );
    C1 = ValueWhen( BearHar4, trL1 );
    C1bar = ValueWhen( BearHar4, trbar1 );
    D = ValueWhen( BearHar, H );
    Dbar = ValueWhen( BearHar, bi );
    ABdXA = SafeDivide( B - A, X - A );
    BCdAB = SafeDivide( B - C1, B - A );
    ADdXA = SafeDivide( D - A, X - A );
    BCdCD = SafeDivide( D - C1, B - C1 );

    for( i = lvb; i > fvb; i-- )
    {
        bearcolor = colorRed;
        linethick = 1;

        if( BearHar[i] )
        {
            drawHarmonicPattern( Xbar[i], X[i], Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i],
                                 D[i], ABdXA[i], BCdAB[i], ADdXA[i], BCdCD[i], topBox_be[i], botBox_be[i],
                                 patternName, ColorRGB( 255, 0, 0 ), ColorRGB( 120, 0, 0 ), ColorRGB( 30, 0, 0 ), 1, -1 );
        }
    }
}

function showBullishABCDPattern( patternName )
{
    BullHar4 = Bull4;
    BullHar = Bull;

    if( lvb > 0 )
    {
        rBullHar4 = Reverse( BullHar4, 0, lvb );
        rBullHar = Reverse( BullHar, 0, lvb );
        rBullHar = ExRem( rBullHar, rBullHar4 );
        BullHar = Reverse( rBullHar, 0, lvb );
    }

    A = ValueWhen( BullHar4, pkH2 );
    Abar = ValueWhen( BullHar4, pkbar2 );
    B = ValueWhen( BullHar4, trL1 );
    Bbar = ValueWhen( BullHar4, trbar1 );
    C1 = ValueWhen( BullHar4, pkH1 );
    C1bar = ValueWhen( BullHar4, pkbar1 );
    D = ValueWhen( BullHar, L );
    Dbar = ValueWhen( BullHar, bi );
    BCdAB = SafeDivide( C1 - B, A - B );
    BCdCD = SafeDivide( C1 - D, C1 - B );

    for( i = lvb; i > fvb; i-- )
    {
        bullcolor = colorGreen;
        linethick = 1;

        if( BullHar[i] AND bu )
        {
            drawABCDPattern( Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i], D[i], BCdAB[i], BCdCD[i],
                             CD_BC_min[i], CD_BC_max[i], patternName, ColorGreen, ColorRGB( 0, 80, 0 ), ColorRGB( 0, 10, 0 ), 1, 1 );
        }
    }
}

function showBearishABCDPattern( patternName )
{
    BearHar4 = Bear4;
    BearHar = Bear;

    if( lvb > 0 )
    {
        rBearHar4 = Reverse( BearHar4, 0, lvb );
        rBearHar = Reverse( BearHar, 0, lvb );
        rBearHar = ExRem( rBearHar, rBearHar4 );
        BearHar = Reverse( rBearHar, 0, lvb );
    }

    A = ValueWhen( BearHar4, trL2 );
    Abar = ValueWhen( BearHar4, trbar2 );
    B = ValueWhen( BearHar4, pkH1 );
    Bbar = ValueWhen( BearHar4, pkbar1 );
    C1 = ValueWhen( BearHar4, trL1 );
    C1bar = ValueWhen( BearHar4, trbar1 );
    D = ValueWhen( BearHar, H );
    Dbar = ValueWhen( BearHar, bi );
    BCdAB = SafeDivide( B - C1, B - A );
    BCdCD = SafeDivide( D - C1, B - C1 );

    for( i = lvb; i > fvb; i-- )
    {
        bearcolor = colorYellow;
        linethick = 1;

        if( BearHar[i] AND be )
        {
            drawABCDPattern( Abar[i], A[i], Bbar[i], B[i], C1bar[i], C1[i], Dbar[i], D[i], BCdAB[i], BCdCD[i],
                             CD_BC_min[i], CD_BC_max[i], patternName, ColorYellow, ColorRGB( 80, 80, 0 ), ColorRGB( 10, 10, 0 ), -2, -1 );
        }
    }
}

// DISPLAY
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "", colorWhite, styleCandle, Null, Null, 0, 0, 1 );
Title = EncodeColor( colorAqua ) +  " | " + Name() + " | "
        + EncodeColor( colorGold ) + StrFormat( " | {{INTERVAL}}" ) + " | "
        + EncodeColor( colorOrange ) + StrFormat( " | {{DATE}}" ) + " | "
        + EncodeColor( colorAqua ) + StrFormat( " | Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) );

if( bu )
{
    if( showGartley )
    {
        // Bullish Gartley Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Gartley_MinXB, Gartley_MaxXB, Gartley_MinAC, Gartley_MaxAC, Gartley_MinXD, Gartley_MaxXD, Gartley_MinBD, Gartley_MaxBD );
        showBullishHarmonicPattern( "Bullish Gartley" );
        BullGartley = Bull;
    }

    if( showBat )
    {
        // Bullish Bat Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Bat_MinXB, Bat_MaxXB, Bat_MinAC, Bat_MaxAC, Bat_MinXD, Bat_MaxXD, Bat_MinBD, Bat_MaxBD );
        showBullishHarmonicPattern( "Bullish Bat" );
        BullBat = Bull;
    }

    if( showAlternateBat )
    {
        // Bullish Alternate Bat Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( AlternateBat_MinXB, AlternateBat_MaxXB, AlternateBat_MinAC, AlternateBat_MaxAC, AlternateBat_MinXD, AlternateBat_MaxXD, AlternateBat_MinBD, AlternateBat_MaxBD );
        showBullishHarmonicPattern( "Bullish Alternate Bat" );
        BullAlternateBat = Bull;
    }

    if( showButterfly )
    {
        // Bullish Butterfly Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Butterfly_MinXB, Butterfly_MaxXB, Butterfly_MinAC, Butterfly_MaxAC, Butterfly_MinXD, Butterfly_MaxXD, Butterfly_MinBD, Butterfly_MaxBD );
        showBullishHarmonicPattern( "Bullish Butterfly" );
        BullButterfly = Bull;
    }

    if( showCrab )
    {
        // Bullish Crab Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Crab_MinXB, Crab_MaxXB, Crab_MinAC, Crab_MaxAC, Crab_MinXD, Crab_MaxXD, Crab_MinBD, Crab_MaxBD );
        showBullishHarmonicPattern( "Bullish Crab" );
        BullCrab = Bull;
    }

    if( showDeepCrab )
    {
        // Bullish DeepCrab Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( DeepCrab_MinXB, DeepCrab_MaxXB, DeepCrab_MinAC, DeepCrab_MaxAC, DeepCrab_MinXD, DeepCrab_MaxXD, DeepCrab_MinBD, DeepCrab_MaxBD );
        showBullishHarmonicPattern( "Bullish Deep Crab" );
        BullDeepCrab = Bull;
    }

    if( showCypher )
    {
        // Bullish Cypher Pattern
        Bull = Bull4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_bu = botBox_bu = 0;
        calculateBullishHarmonicPattern( Cypher_MinXB, Cypher_MaxXB, Cypher_MinAC, Cypher_MaxAC, Cypher_MinXD, Cypher_MaxXD, Cypher_MinBD, Cypher_MaxBD );
        showBullishHarmonicPattern( "Bullish Cypher" );
        BullCypher = Bull;
    }

    if( showABCD )
    {
        // Bullish ABCD Pattern
        Bull = Bull4 = 0;
        CD_BC_min = CD_BC_max = 0;
        calculateBullishABCDPattern( ABCD_MinAC, ABCD_MaxAC, ABCD_MinBD, ABCD_MaxBD, "ABCD" );
        showBullishABCDPattern( "Bullish ABCD" );
        BullABCD = Bull;
    }

    if( showReciprocalABCD )
    {
        // Bullish Reciprocal ABCD Pattern
        Bull = Bull4 = 0;
        CD_BC_min = CD_BC_max = 0;
        calculateBullishABCDPattern( ReciprocalABCD_MinAC, ReciprocalABCD_MaxAC, ReciprocalABCD_MinBD, ReciprocalABCD_MaxBD, "ReciprocalABCD" );
        showBullishABCDPattern( "Bullish Reciprocal ABCD" );
        BullReciprocalABCD = Bull;
    }
}

if( be )
{
    if( showGartley )
    {
        // Bearish Gartley Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Gartley_MinXB, Gartley_MaxXB, Gartley_MinAC, Gartley_MaxAC, Gartley_MinXD, Gartley_MaxXD, Gartley_MinBD, Gartley_MaxBD );
        showBearishHarmonicPattern( "Bearish Gartley" );
        BearGartley = Bear;
    }

    if( showBat )
    {
        // Bearish Bat Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Bat_MinXB, Bat_MaxXB, Bat_MinAC, Bat_MaxAC, Bat_MinXD, Bat_MaxXD, Bat_MinBD, Bat_MaxBD );
        showBearishHarmonicPattern( "Bearish Bat" );
        BearBat = Bear;
    }

    if( showAlternateBat )
    {
        // Bearish Alternate Bat Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( AlternateBat_MinXB, AlternateBat_MaxXB, AlternateBat_MinAC, AlternateBat_MaxAC, AlternateBat_MinXD, AlternateBat_MaxXD, AlternateBat_MinBD, AlternateBat_MaxBD );
        showBearishHarmonicPattern( "Bearish Alternate Bat" );
        BearAlternateBat = Bear;
    }

    if( showButterfly )
    {
        // Bearish Butterfly Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Butterfly_MinXB, Butterfly_MaxXB, Butterfly_MinAC, Butterfly_MaxAC, Butterfly_MinXD, Butterfly_MaxXD, Butterfly_MinBD, Butterfly_MaxBD );
        showBearishHarmonicPattern( "Bearish Butterfly" );
        BearButterfly = Bear;
    }

    if( showCrab )
    {
        // Bearish Crab Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Crab_MinXB, Crab_MaxXB, Crab_MinAC, Crab_MaxAC, Crab_MinXD, Crab_MaxXD, Crab_MinBD, Crab_MaxBD );
        showBearishHarmonicPattern( "Bearish Crab" );
        BearCrab = Bear;
    }

    if( showDeepCrab )
    {
        // Bearish Deep Crab Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( DeepCrab_MinXB, DeepCrab_MaxXB, DeepCrab_MinAC, DeepCrab_MaxAC, DeepCrab_MinXD, DeepCrab_MaxXD, DeepCrab_MinBD, DeepCrab_MaxBD );
        showBearishHarmonicPattern( "Bearish Deep Crab" );
        BearDeepCrab = Bear;
    }

    if( showCypher )
    {
        // Bearish Cypher Pattern
        Bear = Bear4 = 0;
        AD_AX_min = AD_AX_max = 0;
        CD_BC_min = CD_BC_min = 0;
        topBox_be = botBox_be = 0;
        calculateBearishHarmonicPattern( Cypher_MinXB, Cypher_MaxXB, Cypher_MinAC, Cypher_MaxAC, Cypher_MinXD, Cypher_MaxXD, Cypher_MinBD, Cypher_MaxBD );
        showBearishHarmonicPattern( "Bearish Cypher" );
        BearCypher = Bear;
    }

    if( showABCD )
    {
        // Bearish ABCD Pattern
        Bear = Bear4 = 0;
        CD_BC_min = CD_BC_max = 0;
        calculateBearishABCDPattern( ABCD_MinAC, ABCD_MaxAC, ABCD_MinBD, ABCD_MaxBD, "ABCD" );
        showBearishABCDPattern( "Bearish ABCD" );
        BearABCD = Bear;
    }

    if( showReciprocalABCD )
    {
        // Bearish Reciprocal ABCD Pattern
        Bear = Bear4 = 0;
        CD_BC_min = CD_BC_max = 0;
        calculateBearishABCDPattern( ReciprocalABCD_MinAC, ReciprocalABCD_MaxAC, ReciprocalABCD_MinBD, ReciprocalABCD_MaxBD, "ReciprocalABCD" );
        showBearishABCDPattern( "Bearish Reciprocal ABCD" );
        BearReciprocalABCD = Bear;
    }

}

if( PlotFractals )
{
    PlotShapes( shapeSmallCircle * pk, colorRed, 0, H, 10 );
    PlotShapes( shapeSmallCircle * tr, colorBlue, 0, L, -10 );
}

if( showZigZag )
{
    pk = pk;
    tr = tr;
    prch = H;
    prcl = L;
    calculateZigZag();
    //calculateLastSegments();
    Plot( zigzag, "", ColorRGB( 100, 100, 0 ), styleLine | styleNoRescale | styleNoLabel, Null, Null, 0, 0, 1 );
}

// EXPLORATION
if( Status( "action" ) == actionExplore )
{
	/*
    Filter = (
                 BullBat OR BearBat
                 OR BullGartley OR BearGartley
                 OR BullButterfly OR BearButterfly
                 OR BullCrab OR BearCrab
                 OR BullABCD OR BearABCD
                 OR BullAlternateBat OR BearAlternateBat
                 OR BullDeepCrab OR BearDeepCrab
                 OR BullCypher OR BearCypher );
	*/
	Filter = 1;
    lv = LastValue( BullBat OR BearBat
                    OR BullGartley OR BearGartley
                    OR BullButterfly OR BearButterfly
                    OR BullCrab OR BearCrab
                    OR BullABCD OR BearABCD
                    OR BullAlternateBat OR BearAlternateBat
                    OR BullDeepCrab OR BearDeepCrab
                    OR BullCypher OR BearCypher );

    AlertIf( lv , "SOUND C:\\Windows\\Media\\notify.wav", "Audio alert", 2, 0 );

    PatternDirection =
        IIf( BullGartley, 1,
             IIf( BearGartley, -1,
                  IIf( BullBat, 1,
                       IIf( BearBat, -1,
                            IIf( BullButterfly, 1,
                                 IIf( BearButterfly, -1,
                                      IIf( BullCrab, 1,
                                           IIf( BearCrab, -1,
                                                   IIf( BullABCD, 1,
                                                           IIf( BearABCD, -1,
                                                                   IIf( BullAlternateBat, 1,
                                                                           IIf( BearAlternateBat, -1,
                                                                                   IIf( BullDeepCrab, 1,
                                                                                           IIf( BearDeepCrab, -1,
                                                                                                   IIf( BullCypher, 1,
                                                                                                           IIf( BearCypher, -1 , 0 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) );
    TextColor = IIf( patternDirection > 0, ColorRGB( 0, 255, 0 ), ColorRGB( 255, 0, 0 ) );
    PatternValue =
        IIf( BullGartley, 1,
             IIf( BearGartley, 2,
                  IIf( BullBat, 3,
                       IIf( BearBat, 4,
                            IIf( BullButterfly, 5,
                                 IIf( BearButterfly, 6,
                                      IIf( BullCrab, 7,
                                           IIf( BearCrab, 8,
                                                   IIf( BullABCD, 9,
                                                           IIf( BearABCD, 10,
                                                                   IIf( BullAlternateBat, 11,
                                                                           IIf( BearAlternateBat, 12,
                                                                                   IIf( BullDeepCrab, 13,
                                                                                           IIf( BearDeepCrab, 14,
                                                                                                   IIf( BullCypher, 15,
                                                                                                           IIf( BearCypher, 16 , 0 ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) );

    PatternList = "None\nBullish Gartley\nBearish Gartley" +
                  "\nBullish Bat\nBearish Bat" +
                  "\nBullish Butterfly\nBearish Butterfly" +
                  "\nBullish Crab\nBearish Crab" +
                  "\nBullish ABCD\nBearish ABCD" +
                  "\nBullish Alternate Bat\nBearish Alternate Bat" +
                  "\nBullish Deep Crab\nBearish Deep Crab" +
                  "\nBullish Cyper\nBearish Cypher";


    AddMultiTextColumn( PatternValue, PatternList, "Pattern Name", 1.0, TextColor, colorWhite, 125 ); // version 6.2 and Higher
}

_SECTION_END();
5 Likes

This is a wonderful job
I hope that it will be updated and serve as an educational reference and be used as an indicator of patterns
In this way, AB fans are equal to other fans of other programs. (as TV)

thank you for your update

1 Like

thanks, personally i like these ABCD patterns the most. The late David Keleher I had some talks with around 2010. He gave me the code below which he used at the time for long trades ES-mini. I am sure he will not mind me posting this since he died in 2016 at the age of 62 if I remember correctly. But he also used that code that these guys originally posted on these harmonic patterns around 2008/2009

here is his code (this is the most original i could find). Remember this is code from 2010 mostly. I might added a bit for it to work in 2023. It just show the last pattern and it uses selectvalue so you can play around with the mouse

_SECTION_BEGIN( "ABC David .... " );

//GfxSetZOrder( -5 );
//GfxSetCoordsMode( 1 );
//GfxSetZOrder( 5 );


nb = Param( "Minimum Bars", 5, 2, 100, 1 );
pf = ParamToggle( "Plot Fractals", "Off|On", 1 );
tl = Param( "AB=CD Multiplier", 2.62, 1.0, 10, 0.10 );
x = bi = BarIndex();
Lx = LastValue( x );


function svi( array )
{
    return SelectedValue( array );
}


//==============================
f0 = 0;
f1 = 0;
up = 0;
dn = 0;
d = 0;
function fvd( fib )
{
    fv = fib * d;
    ffv = IIf( up, f0 + fv, f0 - fv );
    return IIf( ffv > 0, ffv, Null );
}
//========= GFX Status =========
lvb = Status( "LastVisibleBar" );
fvb = Status( "FirstVisibleBar" );

vizb = lvb - fvb;
miny = Status( "AxisMiny" );
maxy = Status( "AxisMaxy" );
pxtp = Status( "pxcharttop" );
pxbt = Status( "pxChartBottom" );
pxlt = Status( "pxChartLeft" );
pxrt = Status( "pxChartRight" );
pxwd = Status( "pxChartWidth" );
pxht = Status( "pxChartHeight" );
function tpX( x )
{
    return pxlt + ( x - fvb ) * pxwd / ( Lvb - fvb + 1 );
}
function tPY( y )
{
    return pxbt - floor( 0.5 + ( y - miny ) * pxht / ( maxy - miny ) );
}
//========== GFX Line ==========
function gln( xs, ys, xe, ye, col, thk, sty )
{
    xs = SelectedValue( tpx( xs ) );
    ys = SelectedValue( tpy( ys ) );
    xe = SelectedValue( tpx( xe ) );
    ye = SelectedValue( tpy( ye ) );
    GfxSelectPen( col, thk, sty );
    GfxSetBkColor( 16 );
    return IIf( xs AND xe > 0, GfxPolyline( xs, ys, xe, ye ), Null );
}
//======= GFX Flat Line ========
function sln( xs, ys, xe, col, thk, sty )
{
    xs = LastValue( tpx( xs ) );
    ys = LastValue( tpy( ys ) );
    xe = LastValue( tpx( xe ) );
    GfxSelectPen( col, thk, sty );
    GfxSetBkColor( 16 );
    return GfxPolyline( xs, ys, xe, ys );
}
//======== GFX Rectangle =======
function box( xs, ys, xe, ye, col, thk, sty, brush )
{
    xs = LastValue( tpX( xs ) );
    xe = LastValue( tpX( xe ) );
    ys = LastValue( tpY( ys ) );
    ye = LastValue( tpY( ye ) );
    //GfxSetOverlayMode(1); GfxSetBkColor(16);
    GfxSelectPen( col, thk, sty );
    GfxSelectSolidBrush( brush );
    return IIf( xs AND xe > 0, GfxRectangle( xs, ys, xe, ye ), Null );
}

//========================

function pkID( nn )
{
    pk = H == HHV( H, 2 * nn ) AND Ref( HHV( H, nn ), nn ) < H;
    return pk AND Lx - ValueWhen( pk, x ) > nn;
}
function trID( nn )
{
    tr = L == LLV( L, 2 * nn ) AND Ref( LLV( L, nn ), nn ) > L;
    return tr AND Lx - ValueWhen( tr, x ) > nn;
}
pk = pkID( nb );
tr = trID( nb );

px0 = ValueWhen( pk, x, 0 );
tx0 = ValueWhen( tr, x, 0 );
px1 = ValueWhen( pk, x, 1 );
tx1 = ValueWhen( tr, x, 1 );
px2 = ValueWhen( pk, x, 2 );
tx2 = ValueWhen( tr, x, 2 );
pk = IIf( pk, IIf( px2 < tx1, pk, IIf( ValueWhen( pk, H, 2 ) > H, False, pk ) ), pk );
tr = IIf( tr, IIf( tx2 < px1, tr, IIf( ValueWhen( tr, L, 2 ) < L, False, tr ) ), tr );
pk = IIf( pk AND px0 > x, IIf( px0 < tx0, IIf( ValueWhen( pk, H, 0 ) >= H, False, pk ), pk ), pk );
tr = IIf( tr AND tx0 > x, IIf( tx0 < px0, IIf( ValueWhen( tr, L, 0 ) <= L, False, tr ), tr ), tr );
shp = shapeSmallCircle;

if( pf )
{
    PlotShapes( shp * pk, 32, 0, H, 10 );
    PlotShapes( shp * tr, 29, 0, L, -10 );
}

yr1 = ValueWhen( pk, H, 1 );
xr1 = ValueWhen( pk, x, 1 );
yr2 = ValueWhen( pk, H, 2 );
xr2 = ValueWhen( pk, x, 2 );
ys1 = ValueWhen( tr, L, 1 );
xs1 = ValueWhen( tr, x, 1 );
ys2 = ValueWhen( tr, L, 2 );
xs2 = ValueWhen( tr, x, 2 );

beBr = ( yr1 - ys2 ) / ( yr2 - ys2 );
beCr = ( yr1 - ys1 ) / ( yr1 - ys2 );
buBr = ( yr2 - ys1 ) / ( yr2 - ys2 );
buCr = ( yr1 - ys1 ) / ( yr2 - ys1 );
bepo = xs1 > xr1 AND xr1 > xs2 AND xs2 > xr2 AND tr;
bupo = xr1 > xs1 AND xs1 > xr2 AND xr2 > xs2 AND pk;
//==========================
//	    BULLISH ABCD
//==========================
buAbQ = bupo AND buCr > 0.30 AND buCr < 0.80;
Xy = ValueWhen( buAbQ, ys2 );
Xx = ValueWhen( buAbQ, xs2 );
Ay = ValueWhen( buAbQ, yr2 );
Ax = ValueWhen( buAbQ, xr2 );
By = ValueWhen( buAbQ, ys1 );
Bx = ValueWhen( buAbQ, xs1 );
Cy = ValueWhen( buAbQ, yr1 );
Cx = ValueWhen( buAbQ, xr1 );
dH = HighestSince( buAbQ, H );
dL = LowestSince( buAbQ, L );
xmx = Cx + ( bx - ax ) * tl; //AB=CD Bars
Dy = SelectedValue( ValueWhen( x <= xmx, LowestSince( x == Cx, L ) ) );
Dx = SelectedValue( ValueWhen( x <= xmx AND L == Dy, x ) );
dLx = SelectedValue( ValueWhen( dL == L, x ) );
//====== Retrace ======
Dr = ( Cy - Dy ) / ( Cy - By );
Cr = ( Cy - By ) / ( Ay - By );
Br = ( Ay - By ) / ( Ay - Xy );
Res = Ay > Xy;
Sup = Xy > Ay;
XA = IIf( Res AND Dy <= Ay, Ay - Dy, IIf( Res AND Dy > Ay, Dy - Xy,
          IIf( Sup AND Dy >= Ay, Dy - Ay, Xy - Dy ) ) ) / abs( Ay - Xy );
buAbV = Dr > 1.00 AND Dr < 4.50 AND dL == L;
//====== Pivots ======
Xy = svi( Xy );
Ay = svi( Ay );
By = svi( By );
Cy = svi( Cy );
Xx = svi( Xx );
Ax = svi( Ax );
Bx = svi( Bx );
Cx = svi( Cx );
//======= GFX ========
Dxg = svi( tpX( Dx ) );
Cxg = svi( tpX( Cx ) );
Bxg = svi( tpX( Bx ) );
Axg = svi( tpX( Ax ) );
Xxg = svi( tpX( Xx ) );
Dyg = svi( tpY( Dy ) );
Cyg = svi( tpY( Cy ) );
Byg = svi( tpY( By ) );
Ayg = svi( tpY( Ay ) );
Xyg = svi( tpY( Xy ) );
//======== XS & XE =======
xs = Cx + ( Bx - Ax );
xe = Dx + ( Dx - Ax ) * 3.62;


//======== Lo Fibs =======
f0=Cy;  up=By>Cy; dn=Cy>By;  d=Cy-By;
i127=fvd(1.272); i162=fvd(1.618); i200=fvd(2.000);
i224=fvd(2.240); i262=fvd(2.618); i314=fvd(3.141); i362=fvd(3.618);
zon1d=box(Dx,i127,xe,i162,19,1,0,23);
zon2d=box(Dx,i200,xe,i262,21,1,0,23);
zon3d=box(Dx,i314,xe,i362,24,1,0,23);
//======== Hi Fibs =======
f0=Cy;  up=Cy>By; dn=By>Cy;  d=Cy-By;
e127=fvd(1.272); e162=fvd(1.618); e200=fvd(2.000);
e262=fvd(2.618); e314=fvd(3.141); e362=fvd(3.618);
zon1u=box(Dx,e127,xe,e162,19,1,0,23);
zon2u=box(Dx,e200,xe,e262,21,1,0,23);
zon3u=box(Dx,e314,xe,e362,24,1,0,23);

//======== Targets =======
dax = ( Dx - Ax ) * 1.62;
bds = ( Dy - By ) / ( Dx - Bx ) * dax; // BD Slope Line
BsL = LineArray( Bx, By, Dx + dax, Dy + bds );
BsL = gln( Bx, By, Dx + dax, Dy + bds, IIf( bds > 0, 27, IIf( bds < 0, 32, 55 ) ), 1, 1 );
sln( Bx, By, Dx + dax, 11, 1, 1 );
sln( Cx, Cy, Dx + dax, 55, 1, 1 );
sln( Ax, Ay, Dx + dax, 32, 1, 1 );
//====== Plot Pattern ======
gln( Ax, Ay, Bx, By, 34, 2, 1 );
gln( Bx, By, Cx, Cy, 34, 2, 1 );
gln( Cx, Cy, Dx, Dy, 34, 2, 1 ); //Pattern Lines
gln( Ax, Ay, Cx, Cy, 34, 1, 2 );
gln( Bx, By, Dx, Dy, 34, 1, 2 ); //gln(Xx,Xy,Bx,By,34,1,2);//Pattern Connectors
GfxSelectFont( "Tahoma", 8.5, 600 );
GfxSetTextColor( 42 );
GfxSetBkColor( 16 );
GfxSetTextAlign( 6 | 8 );
GfxTextOut( "A", Axg, Ayg - 14 );
GfxTextOut( "C", Cxg, Cyg - 14 );
GfxSetTextAlign( 6 | 0 );
GfxTextOut( "D", Dxg, Dyg + 14 );
GfxTextOut( "B", Bxg, Byg + 14 );
PlotText( NumToStr( Br, 1.2 ), ( Xx + Bx ) / 2, ( Xy + By ) / 2, 51, 16 );
PlotText( NumToStr( Cr, 1.2 ), ( Ax + Cx ) / 2, ( Ay + Cy ) / 2, 51, 16 );
PlotText( NumToStr( Dr, 1.2 ), ( Bx + Dx ) / 2, ( By + Dy ) / 2, 51, 16 );
PlotText( NumToStr( XA, 1.2 ), ( Xx + Dx ) / 2, ( Xy + Dy ) / 2, 10, 16 );
//RequestTimedRefresh(1);
//======== Vic 2B =========
Vbln = IIf( Dx > 0, LineArray( Dx, By, Dx + ( ( Cx - Bx ) * 1.62 ), By ), Null );
Vb2C = LinRegSlope( BsL, 3 ) <= 0 AND Cross( C, Vbln );
V2Hy = ValueWhen( Vb2C, H );
V2Hx = ValueWhen( Vb2C, x );
Pstp = Dy - ( TickSize * 1 );
//IIf(Vb2C,Plot(Vbln,"",11,1),Null);
IIf( Vb2C, sln( Dx, Vbln, Dx + 25, 11, 1, 1 ), Null );
IIf( Vb2C, sln( V2Hx, V2Hy, Dx + 20, 42, 2, 1 ), Null );
PlotText( "Buy = " + StrRight( NumToStr( V2Hy + TickSize, 1.2 ), 5 ), LastValue( V2Hx ) + 10, LastValue( V2Hy ), 42, 16 );
//======== 123 =========
pk = pkID( 2 );
tr = trID( 2 );
yR = SelectedValue( ValueWhen( pk, H ) );
xR = SelectedValue( ValueWhen( pk, x ) );
HH = pk AND ValueWhen( pk, H ) > yR;
Hx = SelectedValue( ValueWhen( HH, x ) );
Hi = SelectedValue( ValueWhen( HH, H ) );
tL = LineArray( x[Hx], H[Hx], x[xr], H[xr], 1 );
//Plot(tL,"",25,8|2048);
p13C = LinRegSlope( BsL, 3 ) > 0 AND Cross( C, tL );
P1Hy = ValueWhen( p13C, H );
P1Hx = ValueWhen( p13C, x );
Pstp = ValueWhen( x == p1Hx, BsL ) - ( TickSize * 1 );
IIf( p13C, sln( P1Hx, P1Hy, Dx + 20, 10, 2, 1 ), Null );
PlotText( "Buy = " + StrRight( NumToStr( P1Hy + TickSize, 1.2 ), 5 ), LastValue( p1Hx ) + 10, LastValue( p1Hy ), 10, 16 );

SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "", colorWhite, styleCandle, Null, Null, 0, 0, 1 );
//Plot(C, "Close",IIf(p13C,10,IIf(Vb2C,42,55)),64);
//Plot(MA(C,200),"\nma",colorWhite,1);

ec10=EncodeColor(10); ec32=EncodeColor(32); ec42=EncodeColor(42);
ec43=EncodeColor(43); ec52=EncodeColor(52); ec55=EncodeColor(55);
dec=1.2;
Title = ec55 + Title = Name() + "     " + FullName() + "      " + ec32 + Date() + "      " + ec42 + "{{INTERVAL}}  " +
   ec55 + "     Open = "   + ec10 + WriteVal(O,dec) + ec55 + "     High = " + ec43 + WriteVal(H,dec) +
   ec55 + "     Low = "    + ec32 + WriteVal(L,dec) + ec55 + "    Close = " + ec52 + WriteVal(C,dec) +
   ec55 + "     Volume = " + ec43 + WriteVal(V,dec) + ec55 + "    ATR-9 = " + ec42 + WriteVal(ATR(9),dec)+
   ec42 + "     Fractal = "+ ec55 + WriteVal(nb,1)  + ec42 + "  Bars " + ec42 + "       x = " + WriteVal(x,1);

//elapsed=GetPerformanceCounter();

//"Time [ms] = "+elapsed;
//GfxSetZOrder( -5 );
_SECTION_END();
8 Likes

Sir, now that its made to accept 50000 char , I try to post the small additions i've tried to make in your code. Please allow me some time.

4 Likes

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.