Stock Portfolio Organizer

The ultimate porfolio management solution.

Shares, Margin, CFD's, Futures and Forex
EOD and Realtime
Dividends and Trust Distributions
And Much More ....
For Portfolio Manager Click Here

WiseTrader Toolbox

#1 Selling Amibroker Plugin featuring:

Advanced Adaptive Indicators
Advanced Pattern Exploration
Neural Networks
And Much More ....
Find Out More Here

ABCD pat for Amibroker (AFL)

Copy & Paste Friendly
/* 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/

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" );
ABCDCmin = Param( "Swing C Min.(AB)", 0.618, 0.3, 1, 0.01 );
ABCDCmax = Param( "Swing C Max.(AB)", 0.786, 0.4, 1, 0.01 );
ABCDDmin = Param( "Swing D Min.(BC)", 1.27, 0.3, 4.0, 0.01 );
ABCDDmax = Param( "Swing D Max.(BC)", 1.618, 0.4, 4.0, 0.01 );
_SECTION_END();


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 )
{
    BullABC = PTvalid AND( ph1 - tl1 ) / ( ph2 - tl1 ) > ABCDCmin AND( ph1 - tl1 ) / ( ph2 - tl1 ) < ABCDCmax;

    BullABCD = 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 );
}

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 )
{
    BearABC = PTvalid AND( ph1 - tl1 ) / ( ph1 - tl2 ) > ABCDCmin AND( ph1 - tl1 ) / ( ph1 - tl2 ) < ABCDCmax;

    BearABCD = 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 );
}

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 ";


Back