Skip to main content

John F. Ehlers Autocorrelation Periodogram for Amibroker (AFL)

Unlis about 11 years ago Amibroker (AFL)

  • Rating:
    3 / 5 (Votes 5)
  • Tags:
    Autocorrelation, Periodogram, Ehlers, ambroker

Good Day! I translated indicator “Autocorrelation Periodogram” from book “Cycle Analytics for Traders”. Who needs the other indicators from this book on AFL I can do without problems. Best Regards, Ilya

Screenshots

Indicator / Formula

Copy & Paste Friendly
/*
	Autocorrelation Periodogram
	2013 John F. Ehlers
*/

SetBarsRequired(sbrAll);

LPeriod = Param("Low-pass Period", 10, 3, 20);
HPeriod = Param("High-pass Period", 48, 22, 80);
IsPlotHeatMap = ParamToggle("Show HeatMap?", "No|Yes", 1);
IsPlotDominantCycle = ParamToggle("Show Dom. Cycle?", "No|Yes");

pi=3.1415926;

function RoofingFilter(lpPeriod, hpPeriod)
{
	alpha1 = (cos(0.707*2*pi / hpPeriod) + sin(0.707*2*pi / hpPeriod) - 1) / cos(0.707*2*pi / hpPeriod);
	a1 = exp(-1.414*pi / lpPeriod);
	b1 = 2*a1*cos(1.414*pi / lpPeriod);
	c2 = b1;
	c3 = -a1*a1;
	c1 = 1 - c2 - c3;
	
	HP = Close;
	Filt = HP;
	
	for(i = 2; i < BarCount; i++)
	{
		HP[i] = ((1 - alpha1 / 2)^2)*(Close[i] - 2*Close[i-1] + Close[i-2]) + 2*(1 - alpha1)*HP[i-1] - ((1 - alpha1)^2)*HP[i-2];
		Filt[i] = c1*(HP[i] + HP[i-1]) / 2 + c2*Filt[i-1] + c3*Filt[i-2];
	}
	
	return Filt;
}

function AGC(lowerCutoff, higherCutoff, acceptableSlope)
{	
	factor = 0;
	accSlope = -acceptableSlope;	//acceptableSlope = 1.5 dB
	halfLC = lowerCutoff / 2;
	halfHC = higherCutoff / 2;
	ratio = 10^(accSlope/20);
	if(halfHC - halfLC > 0)
		factor = ratio^(1/(halfHC - halfLC));
	return factor;
}

function AutocorrelationPeriodogram(data, isHeatMap, isDomCyc)
{
	avgLength = 3;
	dominantCycle = 0;

	//Pearson correlation for each value of lag
	for(lag = 0; lag <= 48; lag++)
	{
		//Set the average length as M
		M = avgLength;
		if(avgLength == 0)
			M = lag;
		//Initialize correlation sums
		Sx = 0;
		Sy = 0;
		Sxx = 0;
		Syy = 0;
		Sxy = 0;
		//Advance samples of both data streams and sum Pearson components
		for(count = 0; count <= M-1; count++)
		{
			X = Ref(data, -count);
			Y = Ref(data, -(lag + count));
			Sx += X;
			Sy += Y;
			Sxx += X^2;
			Syy += Y^2;
			Sxy += X*Y;
		}
		var1 = (M*Sxx - Sx^2)*(M*Syy - Sy^2);
		VarSet("corr" + lag, IIf(var1 > 0, (M*Sxy - Sx*Sy)/sqrt(var1), 0));	//Compute correlation for each value of lag
		//VarSet("corrScale" + lag, IIf(var1 > 0, 0.5*((M*Sxy - Sx*Sy)/sqrt(var1) + 1), 0));	//Scale each correlation to range between 0 and 1
	}
	
	/*//Plot as a Heatmap (for scale each correlation to range between 0 and 1)
	for(period = 3; period <= 48; period++)
	{
		corr = VarGet("corrScale" + period);
		Red = IIf(corr > 0.5, 255*(2 - 2*corr), 255);
		Green = IIf(corr > 0.5, 255, 2*255*corr);
		PlotOHLC( period-1, period-1, period, period, "", ColorRGB( Red, Green, 0 ), styleCloud | styleNoLabel);
	}*/
	
	/*
		The DFT is accomplished by correlating the autocorrelation at each value of lag with the cosine and sine of each period of interest. 
		The sum of the squares of each of these values represents the relative power at each period.
	*/
	for(period = 10; period <= 48; period++)
	{
		cosinePart = 0;
		sinePart = 0;
		
		for(n = 3; n <= 48; n++)
		{
			cosinePart += VarGet("corr" + n)*cos(2*pi*n / period);
			sinePart += VarGet("corr" + n)*sin(2*pi*n / period);
		}
		VarSet("sqSum" + period, cosinePart^2 + sinePart^2);
	}
	
	//EMA is used to smooth the power measurement at each period
	for(period = 10; period <= 48; period++)
		VarSet("r" + period, AMA((VarGet("sqSum" + period))^2, 0.2));

	//Find Maximum Power Level for Normalization
	K = AGC(10, 48, 1.5);
	for(period = 10; period <= 48; period++)
	{
		if(period == 10)
			VarSet("maxPwr", 0);		
		VarSet("maxPwr", IIf(VarGet("r" + period) > VarGet("maxPwr"), K*VarGet("r" + period), VarGet("maxPwr")));
	}
	
	//Normalization power
	for(period = 10; period <= 48; period++)
		VarSet("pwr" + period, VarGet("r" + period)/VarGet("maxPwr"));
		
	//Compute the dominant cycle using the CG of the spectrum
	Spx = 0;
	Sp = 0;
	for(period = 10; period <= 48; period++)
	{
		Spx += IIf(VarGet("pwr" + period) >= 0.5,  period*VarGet("pwr" + period), 0);
		Sp += IIf(VarGet("pwr" + period) >= 0.5, VarGet("pwr" + period), 0);
	}
	dominantCycle = IIf(Sp != 0, Spx / Sp, 0);
	
	if(isHeatMap)
	{
		//Plot as a Heatmap
		for(period = 10; period <= 48; period++)
		{
			pwr = VarGet("pwr" + period);
			Red = IIf(pwr > 0.5, 255, 2*255*pwr);
			Green = IIf(pwr > 0.5, 255*(2*pwr - 1), 0);
			PlotOHLC( period-1, period-1, period, period, "", ColorRGB( Red, Green, 0 ), styleCloud | styleNoLabel, Null, Null, 0, 0);
		}
	}
	
	if(isDomCyc)
		Plot(dominantCycle, "Dominant Cycle", colorBlue, styleThick, Null, Null, 0, 1);
	
	return dominantCycle;
}

filtData = RoofingFilter(LPeriod, HPeriod);
AutocorrelationPeriodogram(filtData, IsPlotHeatMap, IsPlotDominantCycle);

24 comments

about 11 years ago

Dear Ilya,

Thanks for sharing the code, its very good.
Request you please develop & share other indicators mentioned in the book.

Viswanath

about 11 years ago

The book (Free PDF) is available at https://download.e-bookshelf.de/download/0004/0350/03/L-G-0004035003-0002588758.pdf.

Guys interested can down load from there

5. Unlis
about 11 years ago

davidalan, “dominant cycle = 0; syntax error???” – сan you explain what is wrong? I am here simply declare an array and fills it with zeros.

about 11 years ago

Ilya, Autocorrelation Reversals code would be much apreciated.
kv_maligi, your free pdf has only 26 pages.

about 11 years ago

sal157011,
i too realized after some time going thrpugh it. I am searching for full PDF.
I tried to read those pages, but looked Greek to me.

The code “Autocorrelation Periodogram”, after attaching to a chart, gives trend direction & also strength of the trend clearly. As saying goes “A picture reveals 1000 secretes….”

Its superb coding by llya, It seems he is blessed with lots of skills, I am sure he will develop all useful codes.

viswanath

9. Unlis
about 11 years ago

Friends, “Autocorrelation Reversals” waiting for the approval.

10. parfumeur
about 11 years ago

Very nice work. You do need the book to understand what the indicator says.

Do post in the ‘Pastie’ area with “//” comments on the afl posted.

THANK YOU! for your contribution.

11. val2004
about 11 years ago

Tks a lot, autocorrelation reversals would be as well very appreciated

12. val2004
about 11 years ago

Unlis ,something else not related

Have a look please at

https://www.tradingview.com/script/ngr0qRmw-CM-Laguerre-PPO-PercentileRank-Mkt-Tops-Bottoms/

interesting indicator that may be translated into afl

13. Unlis
about 11 years ago

val2004, “https://www.tradingview.com/script/ngr0qRmw-CM-Laguerre-PPO-PercentileRank-Mkt-Tops-Bottoms/” – well, I will do.

16. kv_maligi
about 11 years ago

Dear Unlis,

Plz go through this. Sling shot trading system
https://www.tradingview.com/script/

This seems to be fantastic code. Can you plz develop this

Viswanath

17. davidalan
about 11 years ago

error 31 syntax error,unexpected ‘=’,expecting ‘(’ that’s the error message version 5.9 dominate cycle highlighted in blue

18. hotaro3
about 11 years ago

http://libgen.org/book/index.php?md5=3bffbaffcc01ab1031add7ef11b303df

Link for downloading full text book- cycle analytics for trader

20. kv_maligi
about 11 years ago

Plz have a look at CM sling slot trading system
https://www.tradingview.com/script/GE7tSQK1-CM-Sling-Shot-System/
http://wisestocktrader.com/indicatorpasties/1511-cm-sling-slot-trading-system

I do not know in which language its written, can any AFL expert guys convert this into AFL?

21. kv_maligi
about 11 years ago

Hellow Hotor3,

Can also please paste PDF link for “John Ehlers – Rocket Science for Traders”

Thanks
viswanath

almost 11 years ago

Hi Unlis,

Can please have a look at the MSLIDE, below is the code. can you try to convert it to AFL code.

src = hl2
len=input(13)
w = input(defval=4, title="width", minval=1, maxval=7, step=1)
lrc = linreg(src, len, 0)

lrcColor=change(lrc) >= 0 ? lime:red

plot(lrc, color=lrcColor, linewidth=3)

plot(w>=7?lrc:na, offset=7, color=lrcColor)
plot(w>=6?lrc:na, offset=6, color=lrcColor)
plot(w>=5?lrc:na, offset=5, color=lrcColor)
plot(w>=4?lrc:na, offset=4, color=lrcColor)
plot(w>=3?lrc:na, offset=3, color=lrcColor)
plot(w>=2?lrc:na, offset=2, color=lrcColor)
plot(w>=1?lrc:na, offset=1, color=lrcColor)

plot(w>=7?lrc:na, offset=-7, color=lrcColor)
plot(w>=6?lrc:na, offset=-6, color=lrcColor)
plot(w>=5?lrc:na, offset=-5, color=lrcColor)
plot(w>=4?lrc:na, offset=-4, color=lrcColor)
plot(w>=3?lrc:na, offset=-3, color=lrcColor)
plot(w>=2?lrc:na, offset=-2, color=lrcColor)
plot(w>=1?lrc:na, offset=-1, color=lrcColor)

Thanks

24. derek2209
over 8 years ago

Hello Ilya

On a Daily Chart
I would like to Plot a Weekly “Autocorrelation Periodogram “ in a Pane of its own.
I only need the ( LastValue( dominant Weekly Cycle )


I have tried inserting the lines of code below in the formula
but I get incorrect values for a Weekly Periodogram
I must have lines below in the wrong places
-————————————————————————————-

wc = TimeFrameCompress( Close, inWeekly );
TimeFrameSet( inWeekly );     // switch now to Weekly
TimeFrameRestore();        // restore time frame to original
Plot( TimeFrameExpand(dominantCycle,inWeekly)," dominantCycle Weekly", colorBlue );

Thank you in advance
Derek

Leave Comment

Please login here to leave a comment.