Welcome Features News Download Registration Support FAQ Wish list Links
Advanced stock charting and analysis program

AFL Library

This is read-only version of AFL library entry. Ability to add user formulas and comment is only available from members-only area.

Details:

Formula name: Bullish Percent Index 2004
Author/Uploader: Graham Kavanagh - gkavanagh [at] e-wire.net.au
Date/Time added: 2004-07-20 19:53:56
Origin:
Keywords: Bullish Percent Index
Level: semi-advanced
Flags: indicator

DISCLAIMER: Most formulas present in AFL on-line library are submitted by the users and are provided here on an "as is" and "as available" basis. AmiBroker.com makes no representations or warranties of any kind to the contents or the operation of material presented here. We do not maintain nor provide technical support for 3rd party formulas.
Description:

Replaces the previous BPI I placed here
Creates a composite of the Bullish signals for a group of stocks. The file here is 3 parts combined - Create composite - Plot line chart - Plot P&F of BPI
Change the Box sizings to suit your market stocks.

Formula:

// 3 FILES ARE INCLUDED HERE
// SEPARATE AT THE CUT LINES


///////////////////////////////////////
// FILE 1 CREATE COMPOSITE
///////////////////////////////////////

// Bullish Percent Index
// Buy Signals generated via P&F 
// Graham Kavanagh  09 Jul 2004
// Select your group of stocks and run Scan in AA window


SetBarsRequired(10000,10000);


function ToBox( Price )
{
 Boxes = 
 Min( Price, 0.25 )/0.0625 + 
 Max( ( Min( Price, 1 )-0.25 ) ,0 )/0.125 + 
 Max( ( Min( Price, 5 )-1 ) ,0 )/0.25 + 
 Max( ( Min( Price, 20 )-5 ) ,0 )/0.5 + 
 Max( ( Min( Price, 100 )-20 ) ,0 )/1 + 
 Max( ( Min( Price, 200 )-100 ) ,0 )/2 + 
 Max( ( Min( Price, 500 )-200 ) ,0 )/4 + 
 Max( ( Min( Price, 1000 )-500 ) ,0 )/5 + 
 Max( ( Min( Price, 25000 )-1000 ) ,0 )/50 + 
 Max( ( Price-25000 ) ,0 )/500 ;
 
 return Boxes; 
}

// round boxes down for High and up for Low
Lx = ceil(ToBox(L));
Hx = floor(ToBox(H));

// set variable values for locating peak/troughs of columns
Bar = BarIndex();
BarDate = DateNum();
BarTurn = 0;
DateTurn = 0;
DateEnd = 0;
BarEnd = 0;
fall = 1;
rise = 0;

PFC[0] = Lx[0];

reverse = 3;
dirn = -1; // -1=down, 1=up

for( i = 1; i < BarCount; i++ )
{
 if( Lx[i]<=(PFC[i-1]-1) && V[i]>0 && dirn==-1)         //continue down
 {
  PFC[i] = Lx[i];
  DateEnd[i] = BarDate[i];
  BarEnd[i] = Bar[i];
  fall[i] = 1;
  rise[i] = 0;
 }
 else
 {
  if( Hx[i]>=(PFC[i-1]+Reverse) && Lx[i]>PFC[i-1] && V[i]>0 && dirn==-1) 
//Change direction to up
  {
   dirn = 1;
   PFC[i] = Hx[i];
   BarTurn[i] = Bar[i];
   DateTurn[i] = BarDate[i];
   DateEnd[i] = BarDate[i];
   BarEnd[i] = Bar[i];
   fall[i] = 0;
   rise[i] = 1;
  }
  else
  {
   if( Hx[i]>=(PFC[i-1]+1) && V[i]>0 && dirn==1)         //Continue up
   {
    PFC[i] = Hx[i];
    DateEnd[i] = BarDate[i];
    BarEnd[i] = Bar[i];
    fall[i] = 0;
    rise[i] = 1;
   }
   else
   {
    if( Lx[i]<=(PFC[i-1]-Reverse) && Hx[i]<PFC[i-1] && V[i]>0 && dirn==1)  
//Change direction to down
    {
     dirn = -1;
     PFC[i] = Lx[i];
     BarTurn[i] = Bar[i];
     DateTurn[i] = BarDate[i];
     DateEnd[i] = BarDate[i];
     BarEnd[i] = Bar[i];
     fall[i] = 1;
     rise[i] = 0;
    }
    else
    {
     PFC[i] = PFC[i-1];
     rise[i] = rise[i-1];
     fall[i] = fall[i-1];
    }
   }
  }
 }
}


//Convert boxes to prices for check plotting

b1=0 + 0.25 / 0.0625;
b2=b1 + (1-0.25) / 0.125;
b3=b2 + (5-1) / 0.25;
b4=b3 + (20-5) / 0.5;
b5=b4 + (100-20) / 1;
b6=b5 + (200-100) / 2;
b7=b6 + (500-200) / 4;
b8=b7 + (1000-500) / 5;
b9=b8 + (25000-100) / 50;


function ToPrice( Value )
{
 Price = 
 Min( Value, b1 ) * 0.0625 + 
 Min( Max( Value-b1, 0 ), b2-b1 ) * 0.125 + 
 Min( Max( Value-b2, 0 ), b3-b2 ) * 0.25  + 
 Min( Max( Value-b3, 0 ), b4-b3 ) * 0.5 + 
 Min( Max( Value-b4, 0 ), b5-b4 ) * 1 + 
 Min( Max( Value-b5, 0 ), b6-b5 ) * 2 + 
 Min( Max( Value-b6, 0 ), b7-b6 ) * 4 + 
 Min( Max( Value-b7, 0 ), b8-b7 ) * 5 + 
 Min( Max( Value-b8, 0 ), b9-b8 ) * 50 + 
 Max( Value-b9, 0 ) * 500 ;

  return Price; 
}

bullsig = PFC > ValueWhen( rise AND Ref(fall,1), PFC ) AND rise;

Buy=1;
AddToComposite( bullsig, "~BullPercent", "C" );
AddToComposite( 1, "~BullPercent", "V" );



//=================================%<-----------------------------------------



///////////////////////////////////////
// FILE 2 PLOT LINE CHART
///////////////////////////////////////

// Bullish Percent Index Chart - Line
// Graham Kavanagh  09 Jul 2004

BPI = Foreign( "~BullPercent", "C" )/Foreign( "~BullPercent", "V" )*100; 

Plot( BPI, "BPI", colorRed, styleLine );

GraphXSpace=5;

Title = Name() + " " + Date() + ": BPI Line Chart, BPI = "+ WriteVal(BPI,1) +
"% : Number of Stocks = " + Foreign( "~BullPercent", "V" ) + " : Number of Bull
Signals = " + Foreign( "~BullPercent", "C" );

Plot(30, "", colorGreen, styleLine);
Plot(70, "", colorGreen, styleLine);
Plot(100, "", colorWhite, styleNoLine);
Plot(0, "", colorWhite, styleNoLine);



//=================================%<-----------------------------------------



///////////////////////////////////////
// FILE 2 PLOT POINT & FIGURE CHART
///////////////////////////////////////

// Bullish Percent Index Chart - P&F
// Graham Kavanagh  09 Jul 2004


SetBarsRequired(100000,100000);

box = 2;
reverse = 3;

CX = Foreign( "~BullPercent", "C" )/Foreign( "~BullPercent", "V" )*100;
CF = ceil(Cx/box);
CR = floor(Cx/box);

Bar = BarIndex();
BarDate = DateNum();
BarTurn = 0;
DateTurn = 0;
DateEnd = 0;
BarEnd = 0;

// initialize first element
j = 0;
PFC[j] = CF[0];
PFO[j] = CF[0] + 1;

down = 1;  // By default the first bar is a down bar.
up = 0;

// perform the loop that produces PF Chart
for( i = 1; i < BarCount; i++ )
{
 if( CX[i] <= PFC[j] - 1 && down)   //continue down
 {
  PFC[j] = CF[i];
  PFO[j] = CF[i] + 1;
  DateEnd[j] = BarDate[i];
  BarEnd[j] = Bar[i];
 }
 else
 {
  if( CX[i] >= PFC[j] + Reverse && down)  //Change direction to up
  {
   j++;
   up = 1;
   down = 0;
   PFC[j] = CR[i];
   PFO[j] = CR[i] - 1;
   BarTurn[j] = Bar[i];
   DateTurn[j] = BarDate[i];
   DateEnd[j] = BarDate[i];
   BarEnd[j] = Bar[i];
  }
  else
  {
   if( CX[i] >= PFC[j] + 1 && up)   //Continue up
   {
    PFC[j] = CR[i];
    PFO[j] = CR[i] - 1;
    DateEnd[j] = BarDate[i];
    BarEnd[j] = Bar[i];
   }
   else
   {
    if( CX[i] <= PFC[j] - Reverse && up)   //Change direction to down
    {
     j++;
     up = 0;
     down = 1;
     PFC[j] = CR[i];
     PFO[j] = CR[i] + 1;
     BarTurn[j] = Bar[i];
     DateTurn[j] = BarDate[i];
     DateEnd[j] = BarDate[i];
     BarEnd[j] = Bar[i];
    }
   }
  }
 }
}

delta = BarCount-1 - j;

BarTurns = Ref( BarTurn, -delta);
DateTurns = Ref( DateTurn, -delta);
BarEnds = Ref( BarEnd, -delta);
DateEnds = Ref( DateEnd, -delta);

PFO = Ref( PFO, -delta );
PFC = Ref( PFC, -delta );

Rise = PFC>PFO;
Fall = PFC<PFO;

H = IIf( Ref(Rise, -1), Ref( HHV(PFC, 1), -1 ) - 1, Max(PFO, PFC) ) * box +
box/2;
L = IIf( Ref(Fall, -1), Ref( LLV(PFC, 1), -1 ) + 1, Min(PFO, PFC) ) * box -
box/2;
O = IIf( Ref(Rise, -1), Ref( HHV(PFC, 1), -1 ) - 1, IIf( Ref(Fall, -1), Ref(
LLV(PFC, 1), -1 )+ 1, PFO ) ) * box;

// the difference between Open AND Close is set to box size
// the sign decides if X or O are plotted

C = O + box * IIf( Rise, 1, -1 );

Top = H - box/2;
Bot = L + box/2;

Title = Name() + " " + Date() + ": BPI PnF Chart, H: " + top + ", L: " + bot +
", Box " + box + ", Reversal " + reverse + ": Number of Stocks = " + Foreign(
"~BullPercent", "V" ) + " : Number of Bull Signals = " + Foreign(
"~BullPercent", "C" );

GraphXSpace=5;

Plot(C, "BPI", IIf( Rise, colorBlue, colorRed ), stylePointAndFigure);

Plot(30-box/2, "", colorGreen, styleLine);
Plot(70+box/2, "", colorGreen, styleLine);

Plot(100, "", colorWhite, styleNoLine);
Plot(0, "", colorWhite, styleNoLine);

//--Indicator-End-- 

Comments:

Kevin
kfbinv [at] iinet.net.au
2006-06-14 08:17:29
This indicator as written appears to be forward looking. i.e. the addition of a new days data can change the value calculated for the day before.

I suspect the line at fault is

bullsig = PFC > ValueWhen( rise AND Ref(fall,1), PFC ) AND rise;

The Ref(fall,1) refers to the value of the following days fall array. I think it should be Ref(fall,-1) i.e yesterdays.

I say I think, becuase I am not sure how this code actually works. i am however certain of the forward looking behaviour and how misleading that can be when you back test.
Paul Moore
polomora [at] gmail.com
2009-10-30 10:26:13
I generated this indicator for NASDAQ, and compared it with the symbol $BPCOMPQ on stockcharts.com. The chart shapes are roughly similar, but the values are completely different. For example on 29 October 2009 the calculated value is 19.6%, whereas on stockcharts.com the value is 64%.


About | Privacy | Terms of Use | Contact information
Copyright © 2001 AMIBROKER.COM