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: Gordon Rose
Author/Uploader: Gordon Rose - (email hidden)
Date/Time added: 2004-02-05 00:05:21
Origin: Strong desire to use pivots and patterns as basis for trading setups and trading.
Keywords: pivot fibonacci tcz
Level: semi-advanced
Flags: system,exploration,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:

Both indicator and exploration code for combination of fibonacci retracements identified in "Fibonacci for the Active Trader" by Derrik Hobbes. Determines pivots, draws retracements, and explores for them.

Formula:

// **************************
// BEING EXPLORATION CODE
// **************************

// -- what will be our lookback range for the hh and ll?
nBars = Param("Number of bars", 12, 5, 40);
bTrace = Param("Include trace output", 1, 0, 1);
nNoPivsInSetup = Param("No. Pivs in Setup", 4, 3, 4, 1);
bShowTCZ = Param("Show TCZ", 1, 0, 1); 
nMinBarsBtwPivs = Param("Min. number of bars btw. pivots", 1, 1, 10, 1);
nMinPctBtwPivs = Param("Min. percent diff. btw. pivots", .05, .04, .2, .01);
bLastBarCanBePiv = Param("Last bar can be a pivot", 1, 0, 1); 
retrcTolerance = .01;
tczTolerance = .005;
nNumBarsToScan = 120;

// -- added from exploration version 20040204
nExploreBarIdx = 0;
nExploreDate = 0;
nCurDateNum = 0;
DN = DateNum();
DT = DateTime();

// -- key exploration variables
bTCZLong = False;
bTCZShort = False;
nAnchorPivIdx = 0;

ADX8 = ADX(8);

// 1 - INDICATOR, 2 - COMMENTARY, 3 - SCAN, 
// 4 - EXPLORATION, 5 - BACKTEST / Optimize 
if(Status("action")==1) {
	bDraw = True;
	bUseLastVis = Param("Use last visible bar", 1, 0, 1);
} else {
	bDraw = False;
	bUseLastVis = False;
	bTrace = False;
	nExploreDate = Status("rangetodate");
	for (i=LastValue(BarIndex());i>=0;i--) {
		nCurDateNum = DN[i];
		if (nCurDateNum == nExploreDate) {
			nExploreBarIdx = i;
		}
	}
// -- if(Status("action")==1...
}

GraphXSpace=7;

// -- basic candle chart
// -- if this appears inside if block, strange
//    drawing results!
PlotOHLC(Open, High, Low, Close, 
	"BIdx = " + BarIndex() + 
	"\n" + "O = " + O + "\n"+"H = "+ H + "\n"+"L  = " + L 
	+ "\n"+"C ",
	colorBlack, styleCandle); 

if (bDraw) {
	Plot(MA(C, 21), "21 bar MA", colorAqua, 
		styleLine+styleNoRescale+styleNoLabel);
	Plot(MA(C, 55), "55 bar MA", colorGreen, 
		styleLine+styleNoRescale+styleNoLabel);
	//Plot(MA(C, 233), "233 bar MA", colorDarkRed, 
	//	styleLine+styleNoRescale+styleNoLabel);
}

// -- Create 0-initialized arrays the size of barcount
aHPivs = H - H;
aLPivs = L - L;
aHPivHighs = H - H;
aLPivLows = L - L;
aHPivIdxs = H - H;
aLPivIdxs = L - L;
aAddedHPivs = H - H;
aAddedLPivs = L - L;
aLegVol = H - H;
aRetrcVol = H - H;

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

// -- Initialize value of curTrend
nLastVisBar = LastValue(
	Highest(IIf(Status("barvisible"), BarIndex(), 0)));

curBar = IIf(nlastVisBar > 0 AND bUseLastVis, nlastVisBar, 
	IIf(Status("action")==4 AND nExploreBarIdx > 0, nExploreBarIdx,
	LastValue(BarIndex())));

curTrend = "";
if (aLLVBars[curBar] < aHHVBars[curBar]) 
	curTrend = "D";
else 
	curTrend = "U";

// -- Loop through bars. Search for 
//    entirely array-based approach
//    in future version
/* *******************
	Find main pivots
******************* */

// -- Make sure there are enough bars!
if (curBar >= nNumBarsToScan) {
	for (i=0; i<nNumBarsToScan; i++) {
	
		// -- value of curBar dependent on two parameters
		curBar = IIf(nlastVisBar > 0 AND bUseLastVis, 
			nlastVisBar-i, 
			IIf(Status("action")==4 AND nExploreBarIdx > 0, 
			nExploreBarIdx-i,
			LastValue(BarIndex())-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
	} 
}
/* *******************
	Found main pivots
******************* */

/* *************************
	Finding missed pivot(s)
************************* */

// -- Start at last bar. Reestablish curBar
curBar = 
	IIf(nlastVisBar > 0 AND bUseLastVis, 
	nlastVisBar, 
	IIf(Status("action")==4 AND nExploreBarIdx > 0, 
	nExploreBarIdx,
	LastValue(BarIndex()))
	);

// -- Make sure I found at least two of each above.
if (nHPivs >= 2 AND nLPivs >= 2) {

	lastLPIdx = aLPivIdxs[0];
	lastLPL = aLPivLows[0];
	
	lastHPIdx = aHPivIdxs[0];
	lastHPH = aHPivHighs[0];
	
	nLastHOrLPivIdx = Max(lastLPIdx, lastHPIdx);
	
	nAddPivsRng = curBar - nLastHOrLPivIdx;
	aLLVAfterLastPiv = LLV(L, nAddPivsRng);  
	nLLVAfterLastPiv = aLLVAfterLastPiv[curBar];
	aLLVIdxAfterLastPiv = LLVBars(L, nAddPivsRng);  
	nLLVIdxAfterLastPiv = curBar - aLLVIdxAfterLastPiv[curBar];
	aHHVAfterLastPiv = HHV(H, nAddPivsRng); 
	nHHVAfterLastPiv = aHHVAfterLastPiv[curBar];
	aHHVIdxAfterLastPiv = HHVBars(H, nAddPivsRng); 
	nHHVIdxAfterLastPiv = curBar - aHHVIdxAfterLastPiv[curBar];
	
	// -- Later want to add last high pivot only if
	//    not in buy mode from last and still in trade

	/*
		Note - I'm only interested in adding pivots if I'm in 
		a higher-highs or lower-lows scenario
	*/

	
	// -- OK, let's start where the last high pivot occurs after the
	//    last Low pivot
	if (lastHPIdx > lastLPIdx) {
	
		/*	There are at least two possibilities here. One is that
	   		the previous high was higher, indicating that this is a 
	   		possible short retracement or one in the making.
	   		The other is that the previous high was lower, indicating 
	   		that this is a possible long retracement in the working. 
			However, both depend on opposing pivots. E.g., if I find 
			higher highs, what if I have lower lows?  
		
			If the highs are descending, then I can consider:
	   			- a lower low, and leave it at that
	   			- a higher high and higher low
	   			- a lower low and another lower high
		*/
		if (aHPivHighs[0] < aHPivHighs[1]) {
	
			if (nLLVAfterLastPiv < aLPivLows[0] AND 
				(nLLVIdxAfterLastPiv - lastHPIdx - 1) >= nMinBarsBtwPivs
				AND nLLVIdxAfterLastPiv != curBar	) {
	
				// -- OK, we'll add this as a pivot. 
				//    Mark it for plotting...
				aLPivs[nLLVIdxAfterLastPiv] = 1;
				aAddedLPivs[nLLVIdxAfterLastPiv] = 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] = nLLVAfterLastPiv;
				aLPivIdxs[0] = nLLVIdxAfterLastPiv;
				nLPivs++;
	
			// -- Test whether to add piv given last piv is high 
			//    AND we have lower highs	
			}
	
		// -- Here, the last piv is a high piv, and we have 
		//    higher-highs. The most likely addition is a 
		//    Low piv that is a retracement.
		} else {
	
			if (nLLVAfterLastPiv > aLPivLows[0] AND 
				(nLLVIdxAfterLastPiv - lastHPIdx - 1) >= nMinBarsBtwPivs
				AND nLLVIdxAfterLastPiv != curBar	) {
	
				// -- OK, we'll add this as a pivot. 
				//    Mark it for plotting...
				aLPivs[nLLVIdxAfterLastPiv] = 1;
				aAddedLPivs[nLLVIdxAfterLastPiv] = 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] = nLLVAfterLastPiv;
				aLPivIdxs[0] = nLLVIdxAfterLastPiv;
				nLPivs++;
	
			// -- Test whether to add piv given last piv is high 
			//    AND we have lower highs	
			}	
		// -- The last piv is a high and we have higher highs 
		//    OR lower highs
		}
	
	/* ****************************************************************
		Still finding missed pivot(s). Here, the last piv is a low piv.
	**************************************************************** */
	} else {
	
		// -- First case, lower highs
		if (aHPivHighs[0] < aHPivHighs[1]) {
	
			if (nHHVAfterLastPiv < aHPivHighs[0] AND 
				(nHHVIdxAfterLastPiv - lastLPIdx - 1) >= nMinBarsBtwPivs
				AND nHHVIdxAfterLastPiv != curBar	) {
	
				// -- OK, we'll add this as a pivot. 
				//    Mark that for plotting
				aHPivs[nHHVIdxAfterLastPiv] = 1;
				aAddedHPivs[nHHVIdxAfterLastPiv] = 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] = nHHVAfterLastPiv;
				aHPivIdxs[0] = nHHVIdxAfterLastPiv;
				nHPivs++;
	
			// -- Test whether to add piv given last piv is high 
			//    AND we have lower highs	
			}
	
		// -- Second case when last piv is a low piv, higher highs 
		//    Most likely addition is high piv that is a retracement.
		//    Considering adding a high piv as long as it is higher
		} else {
	
			// -- Where I have higher highs,
			if (nHHVAfterLastPiv > aHPivHighs[0] AND 
				(nHHVIdxAfterLastPiv - lastLPIdx - 1) >= nMinBarsBtwPivs
				AND nHHVIdxAfterLastPiv != curBar	) {
	
				// -- OK, we'll add this as a pivot. 
				//    Mark it for plotting...
				aHPivs[nHHVIdxAfterLastPiv] = 1;
				aAddedHPivs[nHHVIdxAfterLastPiv] = 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] = nHHVAfterLastPiv;
				aHPivIdxs[0] = nHHVIdxAfterLastPiv;
				nHPivs++;
	
			// -- Test whether to add piv given last piv is high 
			//    AND we have lower highs	
			}
	
		}
			
	} 

// -- If there are at least two of each
}

/* ****************************************
// -- Done with finding pivots
***************************************** */ 

if (bDraw) {

	// -- OK, let's plot the pivots using arrows
	PlotShapes(
		IIf(aHPivs==1, shapeDownArrow, shapeNone), 
			colorRed, 0, 	High, Offset=-15);
	PlotShapes(
		IIf(aAddedHPivs==1, shapeDownArrow, shapeNone),
			colorDarkRed, 0, High, Offset=-15);
	PlotShapes(
		IIf(aLPivs==1, shapeUpArrow , shapeNone),		
			colorGreen, 0, Low, Offset=-15);
	PlotShapes(
		IIf(aAddedLPivs==1, shapeUpArrow , shapeNone), 
			colorDarkGreen, 0, Low, Offset=-15);
}

/* ****************************************
// -- Done with discovering and plotting pivots 
***************************************** */ 

// -- I'm going to want to look for possible retracement
risk = 0;
profInc = 0;
nLeg0Pts = 0;
nLeg0Bars = 0;
nLeg0Vol = 0;
nLeg1Pts = 0;
nLeg1Bars = 0;
nLeg1Vol = 0;
nLegBarsDiff = 0;
nRtrc0Pts = 0;
nRtrc0Bars = 0;
nRtrc0Vol = 0;
nRtrc1Pts = 0;
nRtrc1Bars = 0;
nRtrc1Vol = 0;

minRtrc = 0;
maxRtrc = 0;
minLine = 0;
maxLine = 0;
triggerLine = 0;
firstProfitLine = 0;
triggerInc = 0;
triggerPrc = 0;
firstProfitPrc = 0;
retrcPrc = 0;
retrcBar = 0;
retrcBarIdx = 0;
retrcRng = 0;
aRetrcPrc = H-H;
aRetrcPrcBars = H-H;
aRetrcClose = C;
retrcClose = 0;

// -- Do TCZ calcs. Arrangement of pivs very specific
//    for this setup.
if (nHPivs >= 2 AND 
	nLPivs >=2 AND  
	aHPivHighs[0] > aHPivHighs[1] AND
	aLPivLows[0] > aLPivLows[1]) {

	tcz500 = 
	(aHPivHighs[0] -
	(.5 * (aHPivHighs[0] - aLPivLows[1])));

	tcz618 = 
	(aHPivHighs[0] -
	(.618 * (aHPivHighs[0] - aLPivLows[1])));

	tcz786 = 
	(aHPivHighs[0] -
	(.786 * (aHPivHighs[0] - aLPivLows[0])));

	retrcRng = curBar  - aHPivIdxs[0];
	aRetrcPrc = LLV(L, retrcRng);
	retrcPrc = aRetrcPrc[curBar];
	aRetrcPrcBars  = LLVBars(L, retrcRng);
	retrcBarIdx = curBar - aRetrcPrcBars[curBar];
	retrcClose = aRetrcClose[retrcBarIdx];

	// -- bTCZLong setup?
	bTCZLong = (

		// -- Are retracement levels arranged in
		//    tcz order?
		tcz500 >= (tcz786 * (1 - tczTolerance))
		AND 
		// .681 is below .786 for long setups
		tcz618 <= (tcz786 * (1 + tczTolerance))
		AND

		// -- Is the low in the tcz range
		// -- Is the close >= low of tcz range
		//    and low <= high of tcz range
		retrcClose >= ((1 - retrcTolerance) *  tcz618)
		AND
		retrcPrc <= ((1 + retrcTolerance) *  tcz500)
		); 
		
		// -- risk would be high of signal bar minus low of zone
		//risk = 0;

// -- lower highs and lower lows
} else if (nHPivs >= 2 AND nLPivs >=2 
	AND aHPivHighs[0] < aHPivHighs[1] 
	AND aLPivLows[0] < aLPivLows[1]) {

	tcz500 = 
	(aHPivHighs[1] -
	(.5 * (aHPivHighs[1] - aLPivLows[0])));

	tcz618 = 
	(aHPivHighs[0] -
	(.618 * (aHPivHighs[1] - aLPivLows[0])));

	tcz786 = 
	(aHPivHighs[0] -
	(.786 * (aHPivHighs[0] - aLPivLows[0])));

	retrcRng = curBar  - aLPivIdxs[0];
	aRetrcPrc = HHV(H, retrcRng);
	retrcPrc = aRetrcPrc[curBar];
	aRetrcPrcBars  = HHVBars(H, retrcRng);
	retrcBarIdx = curBar - aRetrcPrcBars[curBar];
	retrcClose = aRetrcClose[retrcBarIdx];

	bTCZShort = (
		// -- Are retracement levels arranged in
		//    tcz order?

		// .500 is below .786 for short setups
		tcz500 <= (tcz786 * (1 + tczTolerance))
		AND	
		// .681 is above .786 for short setups
		tcz618 >= (tcz786 * (1 - tczTolerance)) 
		AND

		// -- Is the close <= high of tcz range
		//    and high >= low of tcz range
		retrcClose <= ((1 + retrcTolerance) *  tcz618)
		AND
		retrcPrc >= ((1 - retrcTolerance) *  tcz500)
		); 
		
		// -- Risk would be top of zone - low of signal bar 
		//risk = 0;
}

Filter = (bTCZShort OR bTCZLong);
AddColumn(C, "Close");
AddColumn(IIf(bTCZLong, 76, 83), "L/S", formatChar);

// **************************
// END EXPLORATION CODE
// **************************

// **************************
// BEGIN INDICATOR CODE
// **************************

// -- what will be our lookback range for the hh and ll?
nBars = Param("Number of bars", 12, 5, 40);
bTrace = Param("Include trace output", 1, 0, 1);
nNoPivsInSetup = Param("No. Pivs in Setup", 4, 3, 4, 1);
bShowTCZ = Param("Show TCZ", 1, 0, 1); 
nMinBarsBtwPivs = Param("Min. number of bars btw. pivots", 1, 1, 10, 1);
nMinPctBtwPivs = Param("Min. percent diff. btw. pivots", .05, .04, .2, .01);
bLastBarCanBePiv = Param("Last bar can be a pivot", 1, 0, 1); 
retrcTolerance = .01;
tczTolerance = .005;
nNumBarsToScan = 120;

// -- added from exploration version 20040204
nExploreBarIdx = 0;
nExploreDate = 0;
nCurDateNum = 0;
DN = DateNum();
DT = DateTime();

// -- key exploration variables
bTCZLong = False;
bTCZShort = False;
nAnchorPivIdx = 0;

ADX8 = ADX(8);

// 1 - INDICATOR, 2 - COMMENTARY, 3 - SCAN, 
// 4 - EXPLORATION, 5 - BACKTEST / Optimize 
if(Status("action")==1) {
	bDraw = True;
	bUseLastVis = Param("Use last visible bar", 1, 0, 1);
} else {
	bDraw = False;
	bUseLastVis = False;
	bTrace = False;
	nExploreDate = Status("rangetodate");
	for (i=LastValue(BarIndex());i>=0;i--) {
		nCurDateNum = DN[i];
		if (nCurDateNum == nExploreDate) {
			nExploreBarIdx = i;
		}
	}
// -- if(Status("action")==1...
}

GraphXSpace=7;

// -- basic candle chart
// -- if this appears inside if block, strange
//    drawing results!
PlotOHLC(Open, High, Low, Close, 
	"BIdx = " + BarIndex() + 
	"\n" + "O = " + O + "\n"+"H = "+ H + "\n"+"L  = " + L 
	+ "\n"+"C ",
	colorBlack, styleCandle); 

if (bDraw) {
	Plot(MA(C, 21), "21 bar MA", colorAqua, 
		styleLine+styleNoRescale+styleNoLabel);
	Plot(MA(C, 55), "55 bar MA", colorGreen, 
		styleLine+styleNoRescale+styleNoLabel);
	//Plot(MA(C, 233), "233 bar MA", colorDarkRed, 
	//	styleLine+styleNoRescale+styleNoLabel);
}

// -- Create 0-initialized arrays the size of barcount
aHPivs = H - H;
aLPivs = L - L;
aHPivHighs = H - H;
aLPivLows = L - L;
aHPivIdxs = H - H;
aLPivIdxs = L - L;
aAddedHPivs = H - H;
aAddedLPivs = L - L;
aLegVol = H - H;
aRetrcVol = H - H;

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

// -- Initialize value of curTrend
nLastVisBar = LastValue(
	Highest(IIf(Status("barvisible"), BarIndex(), 0)));

curBar = IIf(nlastVisBar > 0 AND bUseLastVis, nlastVisBar, 
	IIf(Status("action")==4 AND nExploreBarIdx > 0, nExploreBarIdx,
	LastValue(BarIndex())));

curTrend = "";
if (aLLVBars[curBar] < aHHVBars[curBar]) 
	curTrend = "D";
else 
	curTrend = "U";

// -- Loop through bars. Search for 
//    entirely array-based approach
//    in future version
/* *******************
	Find main pivots
******************* */

// -- Make sure there are enough bars!
if (curBar >= nNumBarsToScan) {
	for (i=0; i<nNumBarsToScan; i++) {
	
		// -- value of curBar dependent on two parameters
		curBar = IIf(nlastVisBar > 0 AND bUseLastVis, 
			nlastVisBar-i, 
			IIf(Status("action")==4 AND nExploreBarIdx > 0, 
			nExploreBarIdx-i,
			LastValue(BarIndex())-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
	} 
}
/* *******************
	Found main pivots
******************* */

/* *************************
	Finding missed pivot(s)
************************* */

// -- Start at last bar. Reestablish curBar
curBar = 
	IIf(nlastVisBar > 0 AND bUseLastVis, 
	nlastVisBar, 
	IIf(Status("action")==4 AND nExploreBarIdx > 0, 
	nExploreBarIdx,
	LastValue(BarIndex()))
	);

// -- Make sure I found at least two of each above.
if (nHPivs >= 2 AND nLPivs >= 2) {

	lastLPIdx = aLPivIdxs[0];
	lastLPL = aLPivLows[0];
	
	lastHPIdx = aHPivIdxs[0];
	lastHPH = aHPivHighs[0];
	
	nLastHOrLPivIdx = Max(lastLPIdx, lastHPIdx);
	
	nAddPivsRng = curBar - nLastHOrLPivIdx;
	aLLVAfterLastPiv = LLV(L, nAddPivsRng);  
	nLLVAfterLastPiv = aLLVAfterLastPiv[curBar];
	aLLVIdxAfterLastPiv = LLVBars(L, nAddPivsRng);  
	nLLVIdxAfterLastPiv = curBar - aLLVIdxAfterLastPiv[curBar];
	aHHVAfterLastPiv = HHV(H, nAddPivsRng); 
	nHHVAfterLastPiv = aHHVAfterLastPiv[curBar];
	aHHVIdxAfterLastPiv = HHVBars(H, nAddPivsRng); 
	nHHVIdxAfterLastPiv = curBar - aHHVIdxAfterLastPiv[curBar];
	
	// -- Later want to add last high pivot only if
	//    not in buy mode from last and still in trade

	/*
		Note - I'm only interested in adding pivots if I'm in 
		a higher-highs or lower-lows scenario
	*/

	
	// -- OK, let's start where the last high pivot occurs after the
	//    last Low pivot
	if (lastHPIdx > lastLPIdx) {
	
		/*	There are at least two possibilities here. One is that
	   		the previous high was higher, indicating that this is a 
	   		possible short retracement or one in the making.
	   		The other is that the previous high was lower, indicating 
	   		that this is a possible long retracement in the working. 
			However, both depend on opposing pivots. E.g., if I find 
			higher highs, what if I have lower lows?  
		
			If the highs are descending, then I can consider:
	   			- a lower low, and leave it at that
	   			- a higher high and higher low
	   			- a lower low and another lower high
		*/
		if (aHPivHighs[0] < aHPivHighs[1]) {
	
			if (nLLVAfterLastPiv < aLPivLows[0] AND 
				(nLLVIdxAfterLastPiv - lastHPIdx - 1) >= nMinBarsBtwPivs
				AND nLLVIdxAfterLastPiv != curBar	) {
	
				// -- OK, we'll add this as a pivot. 
				//    Mark it for plotting...
				aLPivs[nLLVIdxAfterLastPiv] = 1;
				aAddedLPivs[nLLVIdxAfterLastPiv] = 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] = nLLVAfterLastPiv;
				aLPivIdxs[0] = nLLVIdxAfterLastPiv;
				nLPivs++;
	
			// -- Test whether to add piv given last piv is high 
			//    AND we have lower highs	
			}
	
		// -- Here, the last piv is a high piv, and we have 
		//    higher-highs. The most likely addition is a 
		//    Low piv that is a retracement.
		} else {
	
			if (nLLVAfterLastPiv > aLPivLows[0] AND 
				(nLLVIdxAfterLastPiv - lastHPIdx - 1) >= nMinBarsBtwPivs
				AND nLLVIdxAfterLastPiv != curBar	) {
	
				// -- OK, we'll add this as a pivot. 
				//    Mark it for plotting...
				aLPivs[nLLVIdxAfterLastPiv] = 1;
				aAddedLPivs[nLLVIdxAfterLastPiv] = 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] = nLLVAfterLastPiv;
				aLPivIdxs[0] = nLLVIdxAfterLastPiv;
				nLPivs++;
	
			// -- Test whether to add piv given last piv is high 
			//    AND we have lower highs	
			}	
		// -- The last piv is a high and we have higher highs 
		//    OR lower highs
		}
	
	/* ****************************************************************
		Still finding missed pivot(s). Here, the last piv is a low piv.
	**************************************************************** */
	} else {
	
		// -- First case, lower highs
		if (aHPivHighs[0] < aHPivHighs[1]) {
	
			if (nHHVAfterLastPiv < aHPivHighs[0] AND 
				(nHHVIdxAfterLastPiv - lastLPIdx - 1) >= nMinBarsBtwPivs
				AND nHHVIdxAfterLastPiv != curBar	) {
	
				// -- OK, we'll add this as a pivot. 
				//    Mark that for plotting
				aHPivs[nHHVIdxAfterLastPiv] = 1;
				aAddedHPivs[nHHVIdxAfterLastPiv] = 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] = nHHVAfterLastPiv;
				aHPivIdxs[0] = nHHVIdxAfterLastPiv;
				nHPivs++;
	
			// -- Test whether to add piv given last piv is high 
			//    AND we have lower highs	
			}
	
		// -- Second case when last piv is a low piv, higher highs 
		//    Most likely addition is high piv that is a retracement.
		//    Considering adding a high piv as long as it is higher
		} else {
	
			// -- Where I have higher highs,
			if (nHHVAfterLastPiv > aHPivHighs[0] AND 
				(nHHVIdxAfterLastPiv - lastLPIdx - 1) >= nMinBarsBtwPivs
				AND nHHVIdxAfterLastPiv != curBar	) {
	
				// -- OK, we'll add this as a pivot. 
				//    Mark it for plotting...
				aHPivs[nHHVIdxAfterLastPiv] = 1;
				aAddedHPivs[nHHVIdxAfterLastPiv] = 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] = nHHVAfterLastPiv;
				aHPivIdxs[0] = nHHVIdxAfterLastPiv;
				nHPivs++;
	
			// -- Test whether to add piv given last piv is high 
			//    AND we have lower highs	
			}
	
		}
			
	} 

// -- If there are at least two of each
}

/* ****************************************
// -- Done with finding pivots
***************************************** */ 

if (bDraw) {

	// -- OK, let's plot the pivots using arrows
	PlotShapes(
		IIf(aHPivs==1, shapeDownArrow, shapeNone), 
			colorRed, 0, 	High, Offset=-15);
	PlotShapes(
		IIf(aAddedHPivs==1, shapeDownArrow, shapeNone),
			colorDarkRed, 0, High, Offset=-15);
	PlotShapes(
		IIf(aLPivs==1, shapeUpArrow , shapeNone),		
			colorGreen, 0, Low, Offset=-15);
	PlotShapes(
		IIf(aAddedLPivs==1, shapeUpArrow , shapeNone), 
			colorDarkGreen, 0, Low, Offset=-15);
}

/* ****************************************
// -- Done with discovering and plotting pivots 
***************************************** */ 

// -- I'm going to want to look for possible retracement
risk = 0;
profInc = 0;
nLeg0Pts = 0;
nLeg0Bars = 0;
nLeg0Vol = 0;
nLeg1Pts = 0;
nLeg1Bars = 0;
nLeg1Vol = 0;
nLegBarsDiff = 0;
nRtrc0Pts = 0;
nRtrc0Bars = 0;
nRtrc0Vol = 0;
nRtrc1Pts = 0;
nRtrc1Bars = 0;
nRtrc1Vol = 0;

minRtrc = 0;
maxRtrc = 0;
minLine = 0;
maxLine = 0;
triggerLine = 0;
firstProfitLine = 0;
triggerInc = 0;
triggerPrc = 0;
firstProfitPrc = 0;
retrcPrc = 0;
retrcBar = 0;
retrcBarIdx = 0;
retrcRng = 0;
aRetrcPrc = H-H;
aRetrcPrcBars = H-H;
aRetrcClose = C;
retrcClose = 0;

// -- Do TCZ calcs. Arrangement of pivs very specific
//    for this setup.
if (nHPivs >= 2 AND 
	nLPivs >=2 AND  
	aHPivHighs[0] > aHPivHighs[1] AND
	aLPivLows[0] > aLPivLows[1]) {

	tcz500 = 
	(aHPivHighs[0] -
	(.5 * (aHPivHighs[0] - aLPivLows[1])));

	tcz618 = 
	(aHPivHighs[0] -
	(.618 * (aHPivHighs[0] - aLPivLows[1])));

	tcz786 = 
	(aHPivHighs[0] -
	(.786 * (aHPivHighs[0] - aLPivLows[0])));

	retrcRng = curBar  - aHPivIdxs[0];
	aRetrcPrc = LLV(L, retrcRng);
	aRetrcPrcBars  = LLVBars(L, retrcRng);
	
	retrcPrc = aRetrcPrc[curBar];
	retrcBarIdx = curBar - aRetrcPrcBars[curBar];
	retrcClose = aRetrcClose[retrcBarIdx];

	// -- bTCZLong setup?
	bTCZLong = (

		// -- Are retracement levels arranged in
		//    tcz order?

		// .500 is above .786 for long setups
		tcz500 >= (tcz786 * (1 - tczTolerance))
		AND 
		// .681 is below .786 for long setups
		tcz618 <= (tcz786 * (1 + tczTolerance))
		AND

		// -- Is the low in the tcz range
		// -- Is the close >= low of tcz range
		//    and low <= high of tcz range
		retrcClose >= ((1 - retrcTolerance) *  tcz618)
		AND
		retrcPrc <= ((1 + retrcTolerance) *  tcz500)
		); 
		
		// -- risk would be high of signal bar minus low of zone
		//risk = 0;

// -- lower highs and lower lows
} else if (nHPivs >= 2 AND nLPivs >=2 
	AND aHPivHighs[0] < aHPivHighs[1] 
	AND aLPivLows[0] < aLPivLows[1]) {

	tcz500 = 
	(aHPivHighs[1] -
	(.5 * (aHPivHighs[1] - aLPivLows[0])));

	tcz618 = 
	(aHPivHighs[0] -
	(.618 * (aHPivHighs[1] - aLPivLows[0])));

	tcz786 = 
	(aHPivHighs[0] -
	(.786 * (aHPivHighs[0] - aLPivLows[0])));

	retrcRng = curBar  - aLPivIdxs[0];
	aRetrcPrc = HHV(H, retrcRng);
	retrcPrc = aRetrcPrc[curBar];
	aRetrcPrcBars  = HHVBars(H, retrcRng);
	retrcBarIdx = curBar - aRetrcPrcBars[curBar];
	retrcClose = aRetrcClose[retrcBarIdx];

	bTCZShort = (
		// -- Are retracement levels arranged in
		//    tcz order?

		// .500 is below .786 for short setups
		tcz500 <= (tcz786 * (1 + tczTolerance))
		AND	
		// .681 is above .786 for short setups
		tcz618 >= (tcz786 * (1 - tczTolerance)) 
		AND

		// -- Is the close <= high of tcz range
		//    and high >= low of tcz range
		retrcClose <= ((1 + retrcTolerance) *  tcz618)
		AND
		retrcPrc >= ((1 - retrcTolerance) *  tcz500)
		); 
		
		// -- Risk would be top of zone - low of signal bar 
		//risk = 0;
}

// -- Show zone if present
if (bTCZShort OR bTCZLong) { 

	// -- Be prepared to see symmetry
	if (bTCZShort) {
		if (aLPivIdxs[0] > aHPivIdxs[0]) {	
			// -- Valuable, useful symmetry information 
			nRtrc0Pts = aHPivHighs[0] - aLPivLows[1];
			nRtrc0Bars = aHPivIdxs[0] - aLPivIdxs[1] + 1;
			nRtrc1Pts = retrcPrc - aLPivLows[0];
			nRtrc1Bars = retrcBarIdx - aLPivIdxs[0] + 1;
		} else {
			nRtrc0Pts = aHPivHighs[1] - aLPivLows[1];
			nRtrc0Bars = aHPivIdxs[1] - aLPivIdxs[1] + 1;
			nRtrc1Pts = aHPivHighs[0] - aLPivLows[0];
			nRtrc1Bars = aHPivIdxs[0] - aLPivIdxs[0] + 1;
		}
	} else { // bLongSetup
		if (aLPivIdxs[0] > aHPivIdxs[0]) {	
			nRtrc0Pts = aHPivHighs[0] - aLPivLows[1];
			nRtrc0Bars = aHPivIdxs[0] - aLPivIdxs[1] + 1;
			nRtrc1Pts = retrcPrc - aLPivLows[0];
			nRtrc1Bars = retrcBarIdx - aLPivIdxs[0] + 1;
		} else {
			nRtrc0Pts = aHPivHighs[1] - aLPivLows[0];
			nRtrc0Bars = aLPivIdxs[0] - aHPivIdxs[1] + 1;
			nRtrc1Pts = aHPivHighs[0] - aLPivLows[0];
			nRtrc1Bars = aLPivIdxs[0] - aHPivIdxs[0] + 1;
		}
	}

	if (bShowTCZ) {
		Plot(
			LineArray(	IIf(bTCZLong, aHPivIdxs[0], aLPivIdxs[0]),
			tcz500, curBar, tcz500 , 0), 
			"tcz500", colorPaleBlue, styleLine);
		Plot(
			LineArray(	IIf(bTCZLong, aHPivIdxs[0], aLPivIdxs[0]),
			tcz618, curBar, tcz618, 0), 
			"tcz618", colorPaleBlue, styleLine);
		Plot(
			LineArray(	IIf(bTCZLong, aHPivIdxs[0], aLPivIdxs[0]),
			tcz786, curBar, tcz786, 0), 
			"tcz786", colorTurquoise, styleLine);
	}

// -- if (bShowTCZ)
}

if (bDraw) {
	Title = Name() + " (" + StrLeft(FullName(), 10) + 
	")  ATR: " + NumToStr(ATR(1), 4.2) + " ( " + 
	NumToStr((C - Ref(C, -1)), 4.2) + " / " +
	NumToStr((((C - Ref(C, -1)) / Ref(C, -1)) * 100), 2.1) + 	"% )  " +
	WriteVal( SelectedValue( DateTime() ), formatDateTime) +
	" \nO: " + Open + 	
	",  \nH: " + High + 
	",  \nL: " + Low + 
	", \nC: " + Close + 	",  \n" +
//	"Risk: " + WriteVal(risk, 2.1) + "%  \n" +
	"Rtrc 0/1 Pts: " + WriteVal(nRtrc0Pts, 2.1) + "/" + 
	WriteVal(nRtrc1Pts, 2.1) + "  \n" +
	"Rtrc 0/1 Bars: " + WriteVal(nRtrc0Bars, 2.0) + "/" +
	WriteVal(nRtrc1Bars, 2.0);
}

// **************************
// END INDICATOR CODE
// **************************


Comments:

Bill Barnard
billbarnard [at] cox.net
2004-02-06 12:13:01
Very nice, Gordon. I will have to read the book.
Chris
chris [at] smithc.freeserve.co.uk
2004-02-12 14:27:09
This looks like a very interesting system.It's clear the system isn't as perfect as it appears since buy and sell signals can dissapear due to subsequent data. So what I would like to do is set the code so even the false siganls will remain in order to back test it porperly. The only problem I have is I'm a bit out of my league with respect to the code. Can anyone explain to me how to alter the code in order to acheive the effect I'm looking for.
Gordon
gordon [at] activecert.com
2004-02-15 12:13:40
Just to clarify, the red and green arrows identify the pivots identified by the code. They can be used to do things such as measuring fib time and price retracements -- basically, recognizing a pattern in the immediate present based on the locations of swing points in the past. These arrays are especially useful:

// -- the price values of the high pivots,
// where aHPivHighs[0] is the most recent
aHPivHighs
// -- Ditto, but for lows
aLPivLows
// -- the bar indexes of the high and low pivots,
// for identifying symmetry in retacements
aHPivIdxs
aLPivIdxs

Gordon
Junior
juniorpsh [at] lycos.co.uk
2004-02-19 21:07:32
The green and red arrows if used as buy and sell signals, it seems too good to me. It is hard to find a stock that doesn't tally with the red and green arrows.

Pardon me that I am not a good programmer, but I have one question to ask.

Will the past green and red arrows change positions when future data comes in?

Regards



Fabiano
Fabiano [at] yehey.com
2004-05-01 11:54:43
Hi

I want take this Formula to find a Buy/Sell Signal
with the Automatic Analysis ,but I got an Error(Missing buy/sell variable assignments)

Can anyone help me ???
Marty
marty.j [at] comast.net
2005-01-09 14:37:06
There is a section in the middle with a Filter already placed, but when I place the additional conditions the filter still does not filter out whrn running Backtest. Any ideas?

Filter = (bTCZShort OR bTCZLong) AND C > $2 and C < $20;

Buy = Filter ;
Sell = aAddedHPivs;
Buy = ExRem(Buy,Sell);
Sell = ExRem(Sell,Buy);
AddColumn(C, "Close");
//AddColumn(IIf(bTCZLong, 76, 83), "L/S", formatChar);

I commented out the above line but still get stocks below $2

Thanks Marty
wilson
wilson_ym_ng [at] hotmail.com
2005-02-04 21:24:11
Can U briefly descript the meanings of the arrows and the interpetation of the graph?
Dominik
tomczykd [at] yahoo.com
2006-02-04 12:28:15
Gordon,

very nice and good job! I use it as BUY & SELL signals. Wirks good, but I saw that the BUY or SELL signals comes correct after 3-4 next sessions? In this case to late.
How you can fix the problem? Is it correct?
Best regards.
Dominik
Amit Jain
jamit_05 [at] rediffmail.com
2006-02-23 00:49:21
I am have a problem with DN[i] in a for loop says cannot access beyond 0 to barcount-1

Besides, could you pls guide me to the usage of this afl, tks.
Don Edwards
dre [at] eftel.com
2006-06-13 23:33:03
Gordon, I have just found your code and its fantastic.

I would like to be able to refer to (say) the last 3 highs and test if they are all higher highs. Also Lower highs for going short (and similar for lows).

Is there a way I can do this using your formula? I can write simple code but thats about all.

Please feel free to use my direct email if you prefer.

Regards, Don.
Hemanshu Pandey
hemanshup [at] yahoo.com
2006-09-17 13:06:01
Hi there,

I am testing the sytem in Indian stock markets. Signals are pretty good and i would like to congratulate Gordon for his work. keep it up!
Ed
emc [at] edcottrell.com
2006-10-23 12:43:50
This code appears to be forward-looking, in the sense that the signals change based on future data. This makes any backtesting using it, as-is, extremely unrealistic. If the signals were stable, it looks like this could be a good system.
xyzz
xyz2222xy [at] yahoo.com
2007-04-15 11:27:45
This formulae is very much baseless. I mean you can see the success of it but when you try the same,

THESE ARROWS ACTUALLY DISAPPEARS.

Be very much cautious if you are using this practically.
Bill
mooneywb [at] yahoo.ca
2008-05-05 08:29:28
This is a brilliant indicator. I thought the originator was mdawe, but I see that it is you, so thank you. Mdawe added to it certainly. Anyway, I have to scroll through every symbol looking for the first green arrow last bar and buy the next day of those I want to buy. Thank you VERY MUCH.
Bill

2008-05-26 14:34:23
Would anyone know how the formula for how to scan for green arrow last bar of this indicator?
pramod

2008-06-04 11:56:20
Gordon,

Thanks.. I know I am pretty late in this.. you posted this in 2006...

Actually before looking at this I was doing something like this... am new to this..:)

////////////////////////
num = Param("trend",3,1,6,1);

FirstVisibleBar = Status( "FirstVisibleBar" );
Lastvisiblebar = Status("LastVisibleBar");

for( b = Firstvisiblebar + num; b <= Lastvisiblebar AND b < BarCount - num; b++)
{
i = num;
ml = 0;
mu = 0;
while( i > 0 )
{
if (L[b] <= L[b-i] && L[b] <= L[b+i] )
{
ml++;
}
if (H[b] >= H[b-i] && H[b] >= H[b+i] )
{
mu++;
}
i--;
}
if ( ml == num )
{
PlotText("\n***\n",b,L[b],colorGreen);
}
if ( mu == num )
{
PlotText("***\n",b,H[b],colorRed);
}
}
ramesh
ram_energy [at] rediffmail.com
2009-06-06 05:09:14
Dear gorden this very good job.

I want take this Formula to find a Buy/Sell Signal
with the Automatic Analysis ,but I got an Error(Missing buy/sell variable assignments)

Can anyone help me ???
gnar
gnargnar [at] sbcglobal.net
2009-07-24 17:43:10
This is a great piece of code!

It seems that a pivot point isn\\\'t formed until there is at least one subsequent close. Which means if you want to use the pivot arrows as buy/sell signals, you pretty much need to trade after hours.

I have to second Ramesh... does anyone know how to make the pivots into buy/sell variable assignments so that we can use the auto analysis to screen large numbers of stocks at once?

Please feel free to contact my email.

Cheers!


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