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: Pivot Finder
Author/Uploader: Mark - (email hidden)
Date/Time added: 2004-07-19 01:06:36
Origin: This has got to be one of the best pivot finders I have found yet. Nobody knows the author who wrote it.... Whoever you are thanks a bunch!!
Keywords:
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:

/* **********************************

Code to automatically identify pivots

********************************** */

// -- what will be our lookback range for the hh and ll?
farback=Param("How Far back to go",100,50,5000,10);
nBars = Param("Number of bars", 12, 5, 40);

// -- Title.

Title = Name() + " (" + StrLeft(FullName(), 15) + ") O: " + Open + ",

H: " + High + ", L: " + Low + ", C: " + Close;

// -- Plot basic candle chart

PlotOHLC(Open, High, Low, Close,

"BIdx = " + BarIndex() +

"\n" + "O = " + O + "\n"+"H = "+ H + "\n"+"L = " + L

+ "\n"+"C ",

colorBlack, styleCandle);

GraphXSpace=7;

// -- Create 0-initialized arrays the size of barcount

aHPivs = H - H;

aLPivs = L - L;

// -- More for future use, not necessary for basic plotting

aHPivHighs = H - H;

aLPivLows = L - L;

aHPivIdxs = H - H;

aLPivIdxs = L - L;

nHPivs = 0;

nLPivs = 0;

lastHPIdx = 0;

lastLPIdx = 0;

lastHPH = 0;

lastLPL = 0;

curPivBarIdx = 0;

// -- looking back from the current bar, how many bars

// back were the hhv and llv values of the previous

// n bars, etc.?

aHHVBars = HHVBars(H, nBars);

aLLVBars = LLVBars(L, nBars);

aHHV = HHV(H, nBars);

aLLV = LLV(L, nBars);

// -- Would like to set this up so pivots are calculated back from

// last visible bar to make it easy to "go back" and see the pivots

// this code would find. However, the first instance of

// _Trace output will show a value of 0

aVisBars = Status("barvisible");

nLastVisBar = LastValue(Highest(IIf(aVisBars, BarIndex(), 0)));

_TRACE("Last visible bar: " + nLastVisBar);

// -- Initialize value of curTrend

curBar = (BarCount-1);

curTrend = "";

if (aLLVBars[curBar] <

aHHVBars[curBar]) {

curTrend = "D";

}

else {

curTrend = "U";

}

// -- Loop through bars. Search for

// entirely array-based approach

// in future version

for (i=0; i<farback; i++) {

curBar = (BarCount - 1) - i;

// -- Have we identified a pivot? If trend is down...

if (aLLVBars[curBar] < aHHVBars[curBar]) {

// ... and had been up, this is a trend change

if (curTrend == "U") {

curTrend = "D";

// -- Capture pivot information

curPivBarIdx = curBar - aLLVBars[curBar];

aLPivs[curPivBarIdx] = 1;

aLPivLows[nLPivs] = L[curPivBarIdx];

aLPivIdxs[nLPivs] = curPivBarIdx;

nLPivs++;

}

// -- or current trend is up

} else {

if (curTrend == "D") {

curTrend = "U";

curPivBarIdx = curBar - aHHVBars[curBar];

aHPivs[curPivBarIdx] = 1;

aHPivHighs[nHPivs] = H[curPivBarIdx];

aHPivIdxs[nHPivs] = curPivBarIdx;

nHPivs++;

}

// -- If curTrend is up...else...

}

// -- loop through bars

}

// -- Basic attempt to add a pivot this logic may have missed

// -- OK, now I want to look at last two pivots. If the most

// recent low pivot is after the last high, I could

// still have a high pivot that I didn't catch

// -- Start at last bar

curBar = (BarCount-1);

candIdx = 0;

candPrc = 0;

lastLPIdx = aLPivIdxs[0];

lastLPL = aLPivLows[0];

lastHPIdx = aHPivIdxs[0];

lastHPH = aHPivHighs[0];

if (lastLPIdx > lastHPIdx) {

// -- Bar and price info for candidate pivot

candIdx = curBar - aHHVBars[curBar];

candPrc = aHHV[curBar];

if (

lastHPH < candPrc AND

candIdx > lastLPIdx AND

candIdx < curBar) {


// -- OK, we'll add this as a pivot...

aHPivs[candIdx] = 1;

// ...and then rearrange elements in the

// pivot information arrays

for (j=0; j<nHPivs; j++) {

aHPivHighs[nHPivs-j] = aHPivHighs[nHPivs-

(j+1)];

aHPivIdxs[nHPivs-j] = aHPivIdxs[nHPivs-(j+1)];

}

aHPivHighs[0] = candPrc ;

aHPivIdxs[0] = candIdx;

nHPivs++;

}

} else {


// -- Bar and price info for candidate pivot

candIdx = curBar - aLLVBars[curBar];

candPrc = aLLV[curBar];

if (

lastLPL > candPrc AND

candIdx > lastHPIdx AND

candIdx < curBar) {


// -- OK, we'll add this as a pivot...

aLPivs[candIdx] = 1;

// ...and then rearrange elements in the

// pivot information arrays

for (j=0; j<nLPivs; j++) {

aLPivLows[nLPivs-j] = aLPivLows[nLPivs-(j+1)];

aLPivIdxs[nLPivs-j] = aLPivIdxs[nLPivs-(j+1)];

}

aLPivLows[0] = candPrc;

aLPivIdxs[0] = candIdx;

nLPivs++;

}

}

// -- Dump inventory of high pivots for debugging

/*

for (k=0; k<nHPivs; k++) {

_TRACE("High pivot no. " + k

+ " at barindex: " + aHPivIdxs[k] + ", "

+ WriteVal(ValueWhen(BarIndex()==aHPivIdxs[k],

DateTime(), 1), formatDateTime)

+ ", " + aHPivHighs[k]);

}

*/

// -- OK, let's plot the pivots using arrows

PlotShapes(

IIf(aHPivs==1, shapeDownArrow, shapeNone), colorRed, 0,

High, Offset=-15);

PlotShapes(

IIf(aLPivs==1, shapeUpArrow , shapeNone), colorGreen, 0,

Low, Offset=-15);

Formula:

  /* **********************************

Code to automatically identify pivots

********************************** */

// -- what will be our lookback range for the hh and ll?
farback=Param("How Far back to go",100,50,5000,10);
nBars = Param("Number of bars", 12, 5, 40);

// -- Title.

Title = Name() + " (" + StrLeft(FullName(), 15) + ") O: " + Open + ", 

H: " + High + ", L: " + Low + ", C: " + Close;

// -- Plot basic candle chart

PlotOHLC(Open, High, Low, Close, 

"BIdx = " + BarIndex() + 

"\n" + "O = " + O + "\n"+"H = "+ H + "\n"+"L = " + L 

+ "\n"+"C ",

colorBlack, styleCandle); 

GraphXSpace=7;

// -- Create 0-initialized arrays the size of barcount

aHPivs = H - H;

aLPivs = L - L;

// -- More for future use, not necessary for basic plotting

aHPivHighs = H - H;

aLPivLows = L - L;

aHPivIdxs = H - H;

aLPivIdxs = L - L;

nHPivs = 0;

nLPivs = 0;

lastHPIdx = 0;

lastLPIdx = 0;

lastHPH = 0;

lastLPL = 0;

curPivBarIdx = 0;

// -- looking back from the current bar, how many bars 

// back were the hhv and llv values of the previous 

// n bars, etc.?

aHHVBars = HHVBars(H, nBars);

aLLVBars = LLVBars(L, nBars);

aHHV = HHV(H, nBars);

aLLV = LLV(L, nBars);

// -- Would like to set this up so pivots are calculated back from

// last visible bar to make it easy to "go back" and see the pivots

// this code would find. However, the first instance of 

// _Trace output will show a value of 0

aVisBars = Status("barvisible");

nLastVisBar = LastValue(Highest(IIf(aVisBars, BarIndex(), 0)));

_TRACE("Last visible bar: " + nLastVisBar);

// -- Initialize value of curTrend

curBar = (BarCount-1);

curTrend = "";

if (aLLVBars[curBar] < 

aHHVBars[curBar]) {

curTrend = "D";

}

else {

curTrend = "U";

}

// -- Loop through bars. Search for 

// entirely array-based approach

// in future version

for (i=0; i<farback; i++) {

curBar = (BarCount - 1) - i;

// -- Have we identified a pivot? If trend is down...

if (aLLVBars[curBar] < aHHVBars[curBar]) {

// ... and had been up, this is a trend change

if (curTrend == "U") {

curTrend = "D";

// -- Capture pivot information

curPivBarIdx = curBar - aLLVBars[curBar];

aLPivs[curPivBarIdx] = 1;

aLPivLows[nLPivs] = L[curPivBarIdx];

aLPivIdxs[nLPivs] = curPivBarIdx;

nLPivs++;

}

// -- or current trend is up

} else {

if (curTrend == "D") {

curTrend = "U";

curPivBarIdx = curBar - aHHVBars[curBar];

aHPivs[curPivBarIdx] = 1;

aHPivHighs[nHPivs] = H[curPivBarIdx];

aHPivIdxs[nHPivs] = curPivBarIdx;

nHPivs++;

}

// -- If curTrend is up...else...

} 

// -- loop through bars

} 

// -- Basic attempt to add a pivot this logic may have missed

// -- OK, now I want to look at last two pivots. If the most 

// recent low pivot is after the last high, I could

// still have a high pivot that I didn't catch

// -- Start at last bar

curBar = (BarCount-1);

candIdx = 0;

candPrc = 0;

lastLPIdx = aLPivIdxs[0];

lastLPL = aLPivLows[0];

lastHPIdx = aHPivIdxs[0];

lastHPH = aHPivHighs[0];

if (lastLPIdx > lastHPIdx) {

// -- Bar and price info for candidate pivot

candIdx = curBar - aHHVBars[curBar];

candPrc = aHHV[curBar]; 

if (

lastHPH < candPrc AND

candIdx > lastLPIdx AND

candIdx < curBar) {


// -- OK, we'll add this as a pivot...

aHPivs[candIdx] = 1;

// ...and then rearrange elements in the 

// pivot information arrays

for (j=0; j<nHPivs; j++) {

aHPivHighs[nHPivs-j] = aHPivHighs[nHPivs-

(j+1)];

aHPivIdxs[nHPivs-j] = aHPivIdxs[nHPivs-(j+1)];

}

aHPivHighs[0] = candPrc ;

aHPivIdxs[0] = candIdx;

nHPivs++;

} 

} else {


// -- Bar and price info for candidate pivot

candIdx = curBar - aLLVBars[curBar];

candPrc = aLLV[curBar]; 

if (

lastLPL > candPrc AND

candIdx > lastHPIdx AND

candIdx < curBar) {


// -- OK, we'll add this as a pivot...

aLPivs[candIdx] = 1;

// ...and then rearrange elements in the 

// pivot information arrays

for (j=0; j<nLPivs; j++) {

aLPivLows[nLPivs-j] = aLPivLows[nLPivs-(j+1)];

aLPivIdxs[nLPivs-j] = aLPivIdxs[nLPivs-(j+1)];

}

aLPivLows[0] = candPrc;

aLPivIdxs[0] = candIdx;

nLPivs++;

}

}

// -- Dump inventory of high pivots for debugging

/*

for (k=0; k<nHPivs; k++) {

_TRACE("High pivot no. " + k

+ " at barindex: " + aHPivIdxs[k] + ", " 

+ WriteVal(ValueWhen(BarIndex()==aHPivIdxs[k], 

DateTime(), 1), formatDateTime)

+ ", " + aHPivHighs[k]);

}

*/

// -- OK, let's plot the pivots using arrows

PlotShapes(

IIf(aHPivs==1, shapeDownArrow, shapeNone), colorRed, 0,

High, Offset=-15);

PlotShapes(

IIf(aLPivs==1, shapeUpArrow , shapeNone), colorGreen, 0, 

Low, Offset=-15);
 

Comments:

John

2004-07-19 03:59:43
Mark,
Go to AFL Library and you find the same code under "Gordon Rose" name. Spot the differance and let us know.
Mark
mleonsprint [at] yahoo.com
2004-10-30 20:36:11
Thanks for the info, and I'll let you spot the difference. I just use the code and am grateful to have it =)
John

2004-11-01 01:39:10
Thanks Mark but I did spot the differance and important one as well. That's the reason I asked you to do the same. "Gordon Rose" code is actually a fraction better. Plot both of them on the same page and you will see for yourself. You must be aware of the fact that some good "buy" signals sometimes disappear if not followed by the closing price increases and this does not make them so good anymore. None of the indicators can predict the future and this one is no different.
Mingfeng
gaomfen [at] benetyne.com
2005-02-28 23:35:41
This is indeed a good indicator, but, it seems there are some bugs. you may find those bugs if you test it by adding Buy and Sell assignment and running the analysis.

looking forward to talking to the author
Bruce
mckoan [at] comcast.net
2005-03-06 15:33:28
I just loaded the Pivot code and applied it to SSRI. A buy signal was generated on 3/3/05 right at the bottom. However, for a test I deleted the pricing for 3/04/05 to determine if the same buy signal would be generated on 03/03/05. The signal was NOT generated. This leads me to believe that Pivot waits an additional day prior to plotting a signal. Based on my findings, the signal was generated a day late. Is the true?
John

2005-03-07 02:42:45
Bruce,
You are right. This is exactly what I tried to tell Mark some time ago.
Bruce Thompson
mckoan [at] comcast.net
2005-03-07 17:13:05
John,
We both know that Pivot does not give its signal on todays close, but rather waits until tomorrow's confirmation pricing.

My question is could additional code be written to determine what tomorrows price must be to generate this signal? I am not a programmer. Looking one day into the future would give us all an advantage and make this indicator very worthwhile!
Bruce
choco
sinhavishal [at] hotmail.com
2005-03-10 19:50:33
Please do not waste our time by posting codes which look into the prices later and then plot signals backward.

I do not need to use code for this. I can just say if prices went higher tommorrow I could have bought yesterday and made profit.

Hope it makes sense to people who waste their time and ohers by adding such useless afl to the library including the Gordon Rose one.
choco
sinhavishal [at] hotmail.com
2005-03-10 20:25:56
Please do not waste our time by posting codes which look into the prices later and then plot signals backward.

I do not need to use code for this. I can just say if prices went higher tommorrow I could have bought yesterday and made profit.

Hope it makes sense to people who waste their time and ohers by adding such useless afl to the library including the Gordon Rose one.
John

2005-03-10 20:27:19
Bruce,
Here you are! I could not do it better than Choco to explain the problem. There is so much rubbish around that one has to learn how to filter it.
No one will tell you how to use AB to make a dollar but on average you will get a new indicator once a week to play with.
Bruce
mckoan [at] comcast.net
2005-03-10 23:43:48
Thanks John and Choco for the advise. Based on the Pivot Indicator my thoughts were knowing the price tomorrow that would trigger a signal, could assist me by defining a buy-stop or sell-stop without waiting until yet another day.

Based on your comments John & Choco, did both of you write your own proprietary code for trading or have you found some of the AFL indicators useful? I will now move on from the Pivot Indicator.
Mingfeng
gaomfen [at] benetyne.com
2005-03-11 23:39:57
I may keep my interest within indicator, not the exploration at the moment. however, I am still concerned the inherent risk this code has. I've been looking closely to the signals across each tick in our markets, in some ocassion, the indicator didn't shoot the sell signal, which is riskier than missing out some buying triggers.

The author obviously attracted a lot attention from the Amibroker users, coz it gives a lot reliable signals, though it lags one day or two probabely. but, what can help if people like myself really wish to use it while noted significant risks inherented in the indicator ( attracted, don't want to give up till find better ones,but, better ones seem not coming)? can the author show up to make improvements, at least it has commercial value???
neoikon

2006-04-26 12:39:57
I agree that the buy/sell signals should be ignored since it uses look-ahead data. However, knowing past pivot points to areas of support or resistance is useful, so I don't agree that its "useless" AFL. It looks a lot like the ZIG ZAG built-in chart.
AO
hulksweider [at] verizon.net
2007-02-10 02:11:48
Operation not allowed
at line 13, column 66:


Title = Name() + " (" + StrLeft(FullName(), 15) + ") O: " + Open +
-----------------------------------------------------------------^

looks interesting but I get the following error -


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