// Downloaded From https://www.WiseStockTrader.com /* ABCD PATTERN DETECTION - based on earlier work done by joy.edakad@gmail.com, see: www.inditraders.com/amibroker/1934-afl-harmonic-patterns.html file: Harmonic1.1.afl (2009) - using ATR type Peaks and Troughs. - Nomenclature of variables, constants and arrays following code from David Keleher. see also: http://harmonictrader.com/blog/2013/08/03/abcd/ http://harmonictrader.com/blog/2013/08/03/alternate-abcd/ Reciprocal ratios following Scott M. Carney, Harmonic Trading (2010) C Point Retracement BC Projection 0.382 2.618 0.50 2.0 0.618 1.618 0.707 1.41 0.786 1.27 0.886 1.13 This code looks for a C point retracement (AB leg retracement) within the margin of error (see parameter window). Then it looks for the reciprocal to that retracement, retracing the BC leg towards point D (again within the same margin of error). The margin of error is set to 5% by default. E.M.Pottasch (Dec 2016). */ Version( 6.0 ); GfxSetCoordsMode( 1 ); GfxSetOverlayMode( 1 ); BullABC = BullABCD = 0; BearABC = BearABCD = 0; pk = tr = pkn = trn = 0; bi = BarIndex(); fvb = FirstVisibleValue( bi ); lvb = LastVisibleValue( bi ); GraphXSpace = 5; SetChartBkColor( colorBlack ); SetChartOptions( 1, chartShowDates, chartGridMiddle, 0, 0, 0 ); SetBarFillColor( IIf( C > O, ColorRGB( 0, 75, 0 ), IIf( C <= O, ColorRGB( 75, 0, 0 ), colorLightGrey ) ) ); Plot( C, "", IIf( C > O, ColorRGB( 0, 255, 0 ), IIf( C <= O, ColorRGB( 255, 0, 0 ), colorLightGrey ) ), 64, Null, Null, 0, 0, 1 ); _SECTION_BEGIN( "Patterns" ); perBull = Param( "Bullish ATR Period", 20, 1, 150, 1 ); perBear = Param( "Bearish ATR Period", 20, 1, 150, 1 ); multBull = Param( "Bullish ATR Multiple", 2, 1, 4, 0.05 ); multBear = Param( "Bearish ATR Multiple", 2, 1, 4, 0.05 ); trailValueClose = ParamToggle( "Trail value", "High/Low|Close", 1 ); //tfrm = in1Minute * Param( "Time Frame (min)", 5, 1, 1440 * 10, 1 ); // 1440 minutes is 1 day tfrm = in1Minute * Interval() / 60 * Param( "Chart Time Frame Factor", 1, 1, 10, 1 ); // factor 1 uses timeframe of chart showATRPivots = ParamToggle( "Show ATR Pivots", "Off|On", 0 ); showLabels = ParamToggle( "Show ATR Pivot Labels", "Off|On", 0 ); bu = ParamToggle( "Show Bullish Pattern", "Off|On", 1 ); be = ParamToggle( "Show Bearish Pattern", "Off|On", 1 ); nBull = Param( "Max Number of Bullish Patterns", 10, 0, 100, 1 ); nBear = Param( "Max Number of Bearish Patterns", 10, 0, 100, 1 ); dABCD = ParamToggle( "Draw ABCD", "Off|On", 1 ); showPatternDevelopmentPoints = ParamToggle( "Show Points of Pattern Development", "Off|On", 1 ); showPatternLabels = ParamToggle( "Show Pattern Labels", "Off|On", 0 ); showPatternName = ParamToggle( "Show Pattern Name", "Off|On", 1 ); _SECTION_END(); _SECTION_BEGIN( "ABCD" ); maxd = Param( "Maximal Retracement Deviation (%)", 5, 0, 100.0, 1 ); _SECTION_END(); ABRet = 0; ABRet[0] = 0.382; ABRet[1] = 0.500; ABRet[2] = 0.618; ABRet[3] = 0.707; ABRet[4] = 0.786; ABRet[5] = 0.886; BCRet = 0; BCRet[0] = 2.618; BCRet[1] = 2.000; BCRet[2] = 1.618; BCRet[3] = 1.410; BCRet[4] = 1.270; BCRet[5] = 1.130; ABRetMin = ABRet - ABRet / 100 * maxd; ABRetMax = ABRet + ABRet / 100 * maxd; BCRetMin = BCRet - BCRet / 100 * maxd; BCRetMax = BCRet + BCRet / 100 * maxd; function ATRtrail_func() { // Trail code largely from: // http://traders.com/Documentation/FEEDbk_docs/2009/06/TradersTips.html if( trailValueClose ) { tvHigh = C; tvLow = C; } else { tvHigh = H; tvLow = L; } sup = tvHigh - multBull * ATR( perBull ); res = tvLow + multBear * ATR( perBear ); trailARRAY = Null; trailstop = 0; for( i = 1; i < BarCount; i++ ) { if( C[ i ] > trailstop AND C[ i - 1 ] > trailstop ) trailstop = Max( trailstop, sup[ i ] ); else if( C[ i ] < trailstop AND C[ i - 1 ] < trailstop ) trailstop = Min( trailstop, res[ i ] ); else trailstop = IIf( C[ i ] > trailstop, sup[ i ], res[ i ] ); trailARRAY[ i ] = trailstop; } return trailARRAY; } TimeFrameSet( tfrm ); trBull = multBull * ATR( perBull ); trBear = multBear * ATR( perBear ); trailArray = ATRtrail_func(); ts = IIf( trailArray > C, trailArray, Null ); // dntrend tl = IIf( trailArray < C, trailArray, Null ); // uptrend TimeFrameRestore(); ts = TimeFrameExpand( ts, tfrm, expandlast ); tl = TimeFrameExpand( tl, tfrm, expandlast ); lll = LLV( L, BarsSince( !IsEmpty( tl ) ) ); lll = IIf( ts, lll, Null ); trn = ts AND L == lll; hhh = HHV( H, BarsSince( !IsEmpty( ts ) ) ); hhh = IIf( tl, hhh, Null ); pkn = tl AND H == hhh; tr = ExRem( Reverse( trn ), Reverse( pkn ) ); pk = ExRem( Reverse( pkn ), Reverse( trn ) ); tr = Reverse( tr ); pk = Reverse( pk ); for( i = 0; i < 3; i++ ) { VarSet( "px" + i, ValueWhen( pk, bi, i ) ); VarSet( "tx" + i, ValueWhen( tr, bi, i ) ); VarSet( "ph" + i, ValueWhen( pk, H, i ) ); VarSet( "tl" + i, ValueWhen( tr, L, i ) ); } ll = tr AND tl1 < tl2; hl = tr AND tl1 > tl2; hh = pk AND ph1 > ph2; lh = pk AND ph1 < ph2; dt = pk AND ph1 == ph2; db = tr AND tl1 == tl2; if( showATRPivots ) { PlotShapes( shapeSmallCircle * tr, IIf( tx1 < px0, ColorRGB( 0, 0, 255 ), colorWhite ), 0, L, -10 ); PlotShapes( shapeSmallCircle * pk, IIf( px1 < tx0, ColorRGB( 255, 0, 0 ), colorWhite ), 0, H, 10 ); } // +++ Bullish ABCD PTvalid = ( px1 > tx1 AND tx1 > px2 AND px2 > tx2 ) AND pk; if( dABCD AND bu ) { for( i = 0; i < 6; i++ ) { ABCDCmin = ABRetMin[i]; ABCDCmax = ABRetMax[i]; ABCDDmin = BCRetMin[i]; ABCDDmax = BCRetMax[i]; BullABCw = PTvalid AND( ph1 - tl1 ) / ( ph2 - tl1 ) > ABCDCmin AND( ph1 - tl1 ) / ( ph2 - tl1 ) < ABCDCmax; BullABC = IIf( BullABCw, BullABCw, BullABC ); BullABCDw = IIf( Nz( LowestSince( BullABC, L ) ) < Nz( ValueWhen( BullABC, ph1 ) ) - ( Nz( ValueWhen( BullABC, ph1 ) ) - Nz( ValueWhen( BullABC, tl1 ) ) ) * ABCDDmin AND Nz( LowestSince( BullABC, L ) ) > Nz( ValueWhen( BullABC, ph1 ) ) - ( Nz( ValueWhen( BullABC, ph1 ) ) - Nz( ValueWhen( BullABC, tl1 ) ) ) * ABCDDmax AND Nz( HighestSince( BullABC, H ) ) <= Nz( ValueWhen( BullABC, ph1 ) ) AND Nz( LowestSince( BullABC, L ) ) < Nz( ValueWhen( BullABC, tl1 ) ) AND Nz( trn ) AND Nz( LowestSince( BullABC, L ) ) == L, True, False ); BullABCD = IIf( BullABCDw, BullABCDw, BullABCD ); } } buAy = ValueWhen( BullABC, ph2 ); buAx = ValueWhen( BullABC, px2 ); buBy = ValueWhen( BullABC, tl1 ); buBx = ValueWhen( BullABC, tx1 ); buCy = ValueWhen( BullABC, ph1 ); buCx = ValueWhen( BullABC, px1 ); buDy = ValueWhen( BullABCD, L ); buDx = ValueWhen( BullABCD, bi ); buBCdAB = ( buCy - buBy ) / ( buAy - buBy ); buBCdCD = ( buCy - buDy ) / ( buCy - buBy ); function drawBullishPattern( i, patternName ) { GfxSelectSolidBrush( ColorRGB( 0, 0, 50 ) ); GfxSetBkColor( colorBlack ); GfxPolygon( buAx[i], buAy[i], buBx[i], buBy[i], buDx[i], buDy[i], buCx[i], buCy[i], buAx[i], buAy[i] ); GfxSelectPen( ColorRGB( 0, 0, 255 ), 2, 0 ); GfxMoveTo( buAx[i], buAy[i] ); GfxLineTo( buBx[i], buBy[i] ); GfxMoveTo( buBx[i], buBy[i] ); GfxLineTo( buCx[i], buCy[i] ); GfxMoveTo( buCx[i], buCy[i] ); GfxLineTo( buDx[i], buDy[i] ); GfxSelectPen( ColorRGB( 0, 0, 255 ), 1, 2 ); GfxMoveTo( buAx[i], buAy[i] ); GfxLineTo( buCx[i], buCy[i] ); GfxMoveTo( buBx[i], buBy[i] ); GfxLineTo( buDx[i], buDy[i] ); if( showPatternName ) { GfxSetTextColor( ColorRGB( 0, 0, 0 ) ); GfxSelectFont( "Helvetica", 10, 700 ); GfxSetBkColor( ColorRGB( 0, 0, 255 ) ); GfxSetTextAlign( 0 | 8 ); GfxTextOut( patternName, buCx[i] + 3, buCy[i] ); } GfxSetTextAlign( 0 | 0 ); GfxSetTextColor( ColorRGB( 0, 0, 255 ) ); GfxSetBkColor( ColorRGB( 0, 0, 0 ) ); GfxSelectFont( "Helvetica", 8, 700 ); GfxTextOut( "" + Prec( buBCdAB[i], 2 ), ( buCx[i] + buAx[i] ) / 2, ( buCy[i] + buAy[i] ) / 2 ); GfxTextOut( "" + Prec( buBCdCD[i], 2 ), ( buBx[i] + buDx[i] ) / 2, ( buBy[i] + buDy[i] ) / 2 ); if( showPatternLabels ) { GfxSetTextColor( ColorRGB( 0, 0, 0 ) ); GfxSelectFont( "Helvetica", 9, 700 ); GfxSetBkColor( ColorRGB( 0, 0, 255 ) ); GfxSetTextAlign( 0 | 24 ); GfxTextOut( "A", buAx[i] - 2, buAy[i] ); GfxTextOut( "B", buBx[i] - 2, buBy[i] ); GfxTextOut( "C", buCx[i] + 1, buCy[i] ); GfxTextOut( "D", buDx[i] + 1, buDy[i] ); } } function drawBullishPatterns() { flag1 = 1; flag2 = 0; cnt = 0; for( i = lvb; i > fvb; i-- ) { if( BullABCD[i] AND flag1 AND cnt < nBull ) { flag1 = 0; flag2 = 1; cnt = cnt + 1; if( BullABCD[i] AND bu AND dABCD ) { drawBullishPattern( i, "Bullish ABCD" ); } } if( BullABC[i] AND flag2 ) { flag1 = 1; flag2 = 0; } } } drawBullishPatterns(); if( showPatternDevelopmentPoints ) { if( bu ) { PlotShapes( shapeDigit3 * BullABC, colorBlue, O, H, 35 ); PlotShapes( shapeSmallCircle * BullABCD, ColorLightBlue, O, L, -10 ); } } // +++ Bearish ABCD PTvalid = ( tx1 > px1 AND px1 > tx2 AND tx2 > px2 ) AND tr; if( dABCD AND be ) { for( i = 0; i < 6; i++ ) { ABCDCmin = ABRetMin[i]; ABCDCmax = ABRetMax[i]; ABCDDmin = BCRetMin[i]; ABCDDmax = BCRetMax[i]; BearABCw = PTvalid AND( ph1 - tl1 ) / ( ph1 - tl2 ) > ABCDCmin AND( ph1 - tl1 ) / ( ph1 - tl2 ) < ABCDCmax; BearABC = IIf( BearABCw, BearABCw, BearABC ); BearABCDw = IIf( Nz( HighestSince( BearABC, H ) ) > Nz( ValueWhen( BearABC, tl1 ) ) + ( Nz( ValueWhen( BearABC, ph1 ) ) - Nz( ValueWhen( BearABC, tl1 ) ) ) * ABCDDmin AND Nz( HighestSince( BearABC, H ) ) < Nz( ValueWhen( BearABC, tl1 ) ) + ( Nz( ValueWhen( BearABC, ph1 ) ) - Nz( ValueWhen( BearABC, tl1 ) ) ) * ABCDDMax AND Nz( LowestSince( BearABC, L ) ) >= Nz( ValueWhen( BearABC, tl1 ) ) AND Nz( HighestSince( BearABC, H ) ) > Nz( ValueWhen( BearABC, ph1 ) ) AND Nz( pkn ) AND Nz( HighestSince( BearABC, H ) ) == H, True, False ); BearABCD = IIf( BearABCDw, BearABCDw, BearABCD ); } } beAy = ValueWhen( BearABC, tl2 ); beAx = ValueWhen( BearABC, tx2 ); beBy = ValueWhen( BearABC, ph1 ); beBx = ValueWhen( BearABC, px1 ); beCy = ValueWhen( BearABC, tl1 ); beCx = ValueWhen( BearABC, tx1 ); beDy = ValueWhen( BearABCD, H ); beDx = ValueWhen( BearABCD, bi ); beBCdAB = ( beBy - beCy ) / ( beBy - beAy ); beBCdCD = ( beDy - beCy ) / ( beBy - beCy ); function drawBearishPattern( i, patternName ) { GfxSelectSolidBrush( ColorRGB( 50, 0, 0 ) ); GfxSetBkColor( colorBlack ); GfxPolygon( beAx[i], beAy[i], beBx[i], beBy[i], beDx[i], beDy[i], beCx[i], beCy[i], beAx[i], beAy[i] ); GfxSelectPen( ColorRGB( 255, 0, 0 ), 2, 0 ); GfxMoveTo( beAx[i], beAy[i] ); GfxLineTo( beBx[i], beBy[i] ); GfxMoveTo( beBx[i], beBy[i] ); GfxLineTo( beCx[i], beCy[i] ); GfxMoveTo( beCx[i], beCy[i] ); GfxLineTo( beDx[i], beDy[i] ); GfxSelectPen( ColorRGB( 255, 0, 0 ), 1, 2 ); GfxMoveTo( beAx[i], beAy[i] ); GfxLineTo( beCx[i], beCy[i] ); GfxMoveTo( beBx[i], beBy[i] ); GfxLineTo( beDx[i], beDy[i] ); if( showPatternName ) { GfxSetTextColor( ColorRGB( 0, 0, 0 ) ); GfxSelectFont( "Helvetica", 10, 700 ); GfxSetBkColor( ColorRGB( 255, 0, 0 ) ); GfxSetTextAlign( 0 | 0 ); GfxTextOut( patternName, beCx[i] + 3, beCy[i] ); } GfxSetTextAlign( 0 | 0 ); GfxSetTextColor( ColorRGB( 255, 0, 0 ) ); GfxSetBkColor( ColorRGB( 0, 0, 0 ) ); GfxSelectFont( "Helvetica", 8, 700 ); GfxTextOut( "" + Prec( beBCdAB[i], 2 ), ( beCx[i] + beAx[i] ) / 2, ( beCy[i] + beAy[i] ) / 2 ); GfxTextOut( "" + Prec( beBCdCD[i], 2 ), ( beBx[i] + beDx[i] ) / 2, ( beBy[i] + beDy[i] ) / 2 ); if( showPatternLabels ) { GfxSetTextColor( ColorRGB( 0, 0, 0 ) ); GfxSelectFont( "Helvetica", 9, 700 ); GfxSetBkColor( ColorRGB( 255, 0, 0 ) ); GfxSetTextAlign( 0 | 24 ); GfxTextOut( "A", beAx[i] - 2, beAy[i] ); GfxTextOut( "B", beBx[i] - 2, beBy[i] ); GfxTextOut( "C", beCx[i] + 1, beCy[i] ); GfxTextOut( "D", beDx[i] + 1, beDy[i] ); } } function drawBearishPatterns() { flag1 = 1; flag2 = 0; cnt = 0; for( i = lvb; i > fvb; i-- ) { if( BearABCD[i] AND flag1 AND cnt < nBear ) { flag1 = 0; flag2 = 1; cnt = cnt + 1; if( BearABCD[i] AND be AND dABCD ) { drawBearishPattern( i, "Bearish ABCD" ); } } if( BearABC[i] AND flag2 ) { flag1 = 1; flag2 = 0; } } } drawBearishPatterns(); function drawPivotLabels() { sz = 5; for( i = lvb; i > fvb; i-- ) { { if( ll[i] ) PlotTextSetFont( "LL", "Arial Black", sz, i, L[i], colorBlue, colorDefault, -25 ); if( hl[i] ) PlotTextSetFont( "HL", "Arial Black", sz, i, L[i], colorBlue, colorDefault, -25 ); if( db[i] ) PlotTextSetFont( "DB", "Arial Black", sz, i, L[i], colorLightBlue, colorDefault, -25 ); if( hh[i] ) PlotTextSetFont( "HH", "Arial Black", sz, i, H[i], colorRed, colorDefault, 20 ); if( lh[i] ) PlotTextSetFont( "LH", "Arial Black", sz, i, H[i], colorRed, colorDefault, 20 ); if( dt[i] ) PlotTextSetFont( "DT", "Arial Black", sz, i, H[i], colorOrange, colorDefault, 20 ); } } } if( showLabels ) drawPivotLabels(); if( showPatternDevelopmentPoints ) { if( be ) { PlotShapes( shapeDigit3 * BearABC, colorRed, O, L, -35 ); PlotShapes( shapeSmallCircle * BearABCD, colorOrange, O, H, 10 ); } } Title = Name() + " | " + Now( 2 ) + " | " + "PIVOT TIMEFRAME: " + tfrm / 60 + " Minutes or " + tfrm / 3600 + " Hours or " + tfrm / ( 3600 * 24 ) + " Days ";