Andrews Pitchfork Trading Strategy (Amibroker Code)

The original article can be found here.

Amibroker code for Andrews Pitchfork:

// Andrews Pitchfork

 
 
SetChartBkColor(ParamColor("bkcolor",colorWhite));
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
si = Param( "Zoom/In Out", 5, -30, 30, 1 );
GraphXSpace = si;
 
////////////////////////////////////////////////////////REGRESION LINEAL /////////////////////////////////////////////////////////////////////
 
LookBack = Param( "Lookback (RegressionChannel)", 17, 2, 300 );
 
NH = LastValue( HHVBars( High, LookBack ) ); // lookback period - can be set by the user if necessary
NL = LastValue( LLVBars( Low , LookBack ) ); // lookback period - can be set by the user if necessary
 
N = 0;
 
if ( NL > NH )
{
      N = NL;
}
else
{
      N = NH;
}
 
Start = 1;
 
X = Cum( Start ); // Set up the x cordinate array of the Linear Regression Line
Y = Close; // Set the y co-ordinate of the Linear Regression line
 
/* Calculate the slope (bconst) and the y intercept (aconst) of the line */
 
SUMX    = LastValue( Sum( X, N ) );
SUMY    = LastValue( Sum( Y, N ) );
SUMXY   = LastValue( Sum( X * Y, N ) );
SUMXSqd = LastValue( Sum( X * X, N ) );
SUMSqdX = LastValue( SUMX * SUMX );
 
bconst = ( N * SUMXY - SUMX * SUMY ) / ( N * SUMXSqd - SUMSqdX );
aconst = ( SUMY - bconst * ( SUMX ) ) / N;
 
/* Force the x value to be very negative so the graph does not apear before the
lookback period */
 
Domain = IIf ( X > LastValue( X ) - N, 1 , -1e10 );
Xvar = X * Domain;
 
/* Linear Regression Line */
 
Yvar = aconst + bconst * Xvar;
 
Plot( Yvar + LastValue( HHV( High - Yvar, N ) ), "Upper Channel", colorBrown, styleDots | styleNoLabel );
Plot( Yvar, "Middle Channel", colorBrown, styleDots | styleNoLabel );
Plot( Yvar - LastValue( HHV( Yvar - Low , N ) ), "Lower Channel", colorBrown, styleDots | styleNoLabel );
 
numbars = SelectedValue( Cum( Status( "barvisible" ) ) );
fraction = IIf( StrRight( Name(), 3 ) == "", 3.2, 3.2 );
 
hts = Param ( "Text Shift", -50, -100, 100, 10 );
 
PlotText( "" + WriteVal( Yvar + LastValue( HHV( High - Yvar, N ) ), fraction ),
          SelectedValue( BarIndex() + 13 ) - 13, SelectedValue( Yvar + LastValue( HHV( High - Yvar, N ) ) ), 2 );
 
PlotText( "" + WriteVal( Yvar, fraction ),
          SelectedValue( BarIndex() + 13 ) - 13, SelectedValue( Yvar ), 2 );
 
PlotText( "" + WriteVal( Yvar - LastValue( HHV( Yvar - Low , N ) ), fraction ),
          SelectedValue( BarIndex() + 13 ) - 13, SelectedValue( Yvar - LastValue( HHV( Yvar - Low , N ) ) ), 2 );
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
SetBarsRequired( 999999,999999);
 
echng=0;
bi=BarIndex();
sbi=SelectedValue(bi);
 
// Pct threshhold for peak() & trough()
 
Zigpct=Param("Zigpct",4.6,1.0,30.0,0.1,0);
 
zema=EMA(C,14);
zpr=IIf(ROC(zema,1) > 0,H,L);
zag=Zig(zpr,zigpct);
tr=Ref(zag,-1) > zag AND zag < Ref(zag,1);
pk=Ref(zag,-1) < zag AND zag > Ref(zag,1);
pkprice=ValueWhen(pk,zpr);
trprice=ValueWhen(tr,zpr);
 
 
pklast=IIf(BarsSince(pk) < BarsSince(tr),1,0);
trlast=IIf(BarsSince(tr) < BarsSince(pk),1,0);
 
 
pk_id=((pklast OR tr) AND pkprice*(1-(zigpct*0.01)) > L ) AND NOT ( pk AND (H - L)/L >= 0.01 * zigpct);
tr_id=((trlast OR pk) AND H > trprice*(1+(zigpct*0.01)) ) AND NOT ( tr AND (H - L)/L >= 0.01 * zigpct);
 
// The pk_id/tr_id conditions can recur before the next pk or tr
pk_id=ExRem(pk_id,tr_id);
tr_id=ExRem(tr_id,pk_id);
 
pk_idlast=IIf(BarsSince(pk_id) < BarsSince(tr_id),1,0);
tr_idlast=IIf(BarsSince(tr_id) < BarsSince(pk_id),1,0);
 
Lookbk=IIf(pk_idlast,BarsSince(pk),BarsSince(tr));
 

xtsn=Param("Extension",62,1,2500,1);
 

shift=Param("Shift",0,-2000,2000,0.01);
 

alimit=Param("Angle Limit",40,1,180,1);
 

bkgrndcolor=ParamColor("Background Color",colorWhite);
pitchforkcolor=ParamColor("Pitchfork Color",colorWhite);
 

 
//pline1=Peak(H,Zigpct,1);
//tline1=Trough(L,Zigpct,1);
pline1=pkprice;
tline1=trprice;
// Identify the pivots.
 
pzag1=pline1 != Ref(pline1,-1);
tzag1=tline1 != Ref(tline1,-1);
 

 
zagx1=0;
zagx2=0;
zagx3=0;
zagy1=0;
zagy2=0;
zagy3=0;
 
for ( i = sbi - Lookbk[sbi], zagfnd = 0, pzagfnd = 0, tzagfnd = 0 ; i >= 0 && zagfnd < 3; i-- ) {
    if ( pzag1[i] || tzag1[i] ) {
        if ( pzag1[i] && NOT pzagfnd ) {
             zagfnd=zagfnd+1;
             pzagfnd=1;
             tzagfnd=0;
             if ( zagfnd == 1 ) {
                 zagx1[sbi]=i;
                 zagy1[sbi]=pline1[i];
             } else if (zagfnd == 2) {
                 zagx2[sbi]=i;
                 zagy2[sbi]=pline1[i];
             } else if (zagfnd == 3) {
                 zagx3[sbi]=i;
                 zagy3[sbi]=pline1[i];
             }
        } else if ( tzag1[i] && NOT tzagfnd ) {
             zagfnd=zagfnd+1;
             tzagfnd=1;
             pzagfnd=0;
             if ( zagfnd == 1 ) {
                 zagx1[sbi]=i;
                 zagy1[sbi]=tline1[i];
             } else if (zagfnd == 2) {
                 zagx2[sbi]=i;
                 zagy2[sbi]=tline1[i];
             } else if (zagfnd == 3) {
                 zagx3[sbi]=i;
                 zagy3[sbi]=tline1[i];
             }
        }
    }
 
    if ( zagfnd == 3 ) {  // Got 3 candidate peak/trough points
 
        echng=0;
        midx=0;
        midy=0;
        Handle=0;
        Top=0;
        Bot=0;
 
        // Determine Midpoint between the rightmost 2 pivots and the slope from the
        // leftmost pivot to the midpoint.
 
        Midx[sbi]=zagx2[sbi] + (zagx1[sbi]-zagx2[sbi]) / 2;
        Midy[sbi]=exp( log(zagy1[sbi]) - ( log(zagy1[sbi])-log(zagy2[sbi]) ) /2);
        echng=(log(midy[sbi])-log(zagy3[sbi]))/(midx[sbi]-zagx3[sbi]);
 
        // Apply the Angle Limit filter
 
        angle_rad = atan(echng);//radians
        angle_deg = 100 * angle_rad * 180/3.1416;//degrees
 
        if ( angle_deg < -alimit || angle_deg > alimit ) { // Too steep, reset the search
                                                           // to begin from the 2nd pivot found
            if ( tzagfnd == 1 ) {  // was tr,pk,tr so switch to pk,tr,pk
                tzagfnd = 0;
                pzagfnd = 1;
                zagfnd = 1;
                zagx1[sbi]=zagx2[sbi];
                zagy1[sbi]=zagy2[sbi];
                i = zagx1[sbi];
                zagx2=0;
                zagx3=0;
                zagy2=0;
                zagy3=0;
            } else {  // was pk,tr,pk so switch to tr,pk,tr
                tzagfnd = 1;
                pzagfnd = 0;
                zagfnd = 1;
                zagx1[sbi]=zagx2[sbi];
                zagy1[sbi]=zagy2[sbi];
                i = zagx1[sbi];
                zagx2=0;
                zagx3=0;
                zagy2=0;
                zagy3=0;
            } 
       }
    }
}
 

 
for ( j=zagx3[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
   Handle[j]=exp(log(zagy3[sbi]) + n*echng) + shift;
}
 
// High & low median lines.
if ( (exp(log(zagy2[sbi]) + (sbi-zagx2[sbi])*echng)) 
     > (exp(log(zagy1[sbi]) + (sbi-zagx1[sbi])*echng)) ) {  // Which one is top?
   for ( j=zagx2[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
      top[j]=exp(log(zagy2[sbi]) + n*echng) + shift;
   }
   for ( j=zagx1[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
      bot[j]=exp(log(zagy1[sbi]) + n*echng) + shift;
   }
} else {
   for ( j=zagx2[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
      bot[j]=exp(log(zagy2[sbi]) + n*echng) + shift;
   }
   for ( j=zagx1[sbi],n=0 ; j < Min(sbi+xtsn,BarCount) ; j++,n++ ) {
      top[j]=exp(log(zagy1[sbi]) + n*echng) + shift;
   }
}
 
Hcolor=IIf(Handle==0,bkgrndcolor,IIf(Ref(handle,-1)== 0 AND handle != 0, bkgrndcolor,pitchforkcolor));
Tcolor=IIf(Top==0,bkgrndcolor,IIf(Ref(top,-1)== 0 AND top != 0, bkgrndcolor,pitchforkcolor));
Bcolor=IIf(Bot==0,bkgrndcolor,IIf(Ref(bot,-1)== 0 AND bot != 0, bkgrndcolor,pitchforkcolor));
 
Htitle=EncodeColor(pitchforkcolor)
      + StrFormat("\nAndrews: pct=%g lkbk=%g shft=%g alimit=%g Angle=%3.2f 
Handle=",Zigpct, Lookbk, shift, alimit, 100 * atan(echng) * 180/3.1416);
 
Plot(Handle,Htitle,Hcolor,styleLine+styleThick+styleNoRescale);
Plot(Bot,EncodeColor(pitchforkcolor)+"Bot=",colorGreen,styleLine+styleThick+styleNoRescale);
Plot(Top,EncodeColor(pitchforkcolor)+"Top=",colorViolet,styleLine+styleThick+styleNoRescale);
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
_SECTION_BEGIN("In Daily Price");
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 ) ) ));
 
TimeFrameSet(inDaily);
MA3 = MA(C,3);
Cl = C;
TimeFrameRestore();
MA3=(TimeFrameExpand( MA3, inDaily));
Cl=(TimeFrameExpand( Cl, inDaily));
barcolor =IIf(C > O , colorPaleGreen,IIf(C < O,colorPink, colorBlack ) );
 
PlotOHLC( IIf(Open<Close, Open, Close),High,Low,
           IIf(Open<Close, Close, Open), "Close", barColor, styleBar+styleThick+styleNoTitle );
 
_SECTION_END();
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
_SECTION_BEGIN("Price, Hawamer");
 
SetBarsRequired(sbrAll);
daynum= Now(9);//day of the week
SatSun= IIf((daynum==1 OR daynum==7),1,0);
dec= IIf(StrRight(Name(),3) == "", 3.2, 3.2);
dec= (Param("Decimals",2,0,7,1)/10)+1;
uc= ParamColor("Up Candle Fill Color",19);
dc= ParamColor("Dn Candle Fill Color",24);
nc= ParamColor("Neutral Fill Color",16);
bc= BarCount-1;
x= BarIndex();
Lx= LastValue(x);
sx= SelectedValue(x);
//==============================
SetBarFillColor(IIf(C>O,43,IIf(C<O,32,nc)));
Plot(C,"",IIf(C>O,27,IIf(C<O,38,16)),64);
 
_SECTION_END();
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
_SECTION_BEGIN( "Magnified Market Price" );
//by Vidyasagar, vkunisetty@yahoo.com//
FS = Param( "Font Size", 25, 11, 100, 1 );
GfxSelectFont( "Times New Roman", FS, 700, True );
GfxSetBkMode( colorWhite );
GfxSetTextColor( ParamColor( "Color", colorWhite ) );
Hor = Param( "Horizontal Position", 420, 1, 1200, 1 );
Ver = Param( "Vertical Position", 100, 1, 830, 1 );
GfxTextOut( "" + C, Hor , Ver );
GfxTextOut( Name(), Hor, Ver-50 );
 
GfxSetTextColor( ParamColor( "ColorY", colorWhite ) );
GfxTextOut( "" + V, Hor , Ver + 45 );
 
YC = TimeFrameGetPrice( "C", inDaily, -1 );
DD = Prec( C - YC, 2 );
xx = Prec( ( DD / YC ) * 100, 2 );
GfxSelectFont( "Times New Roman", 20, 700, True );
GfxSetBkMode( colorWhite );
GfxSetTextColor( ParamColor( "Color", colorRed ) );
GfxTextOut( "" + DD + " (" + xx + "%)", Hor , Ver + 90 );
 
_SECTION_END();