Quote from TSOKAKIS:
An oscillator array y may have a linear trend yL.
After the linear detrending, the new y-yL may be analysed into a sum of sinusoidal terms.
y-yL=g1*sin(2*pi*f1*(t-t1)+phi1)+g2*sin(2*pi*f2*(t-t1)+phi2)+...
We shall examine here the result of an elementary Fourier analysis fundamental frequency and its 2nd and 3rd harmonics
y=yL+g1*sin(2*pi*f1*(t-t1)+phi1)+g2*sin(2*pi*f2*(t-t1)+phi2)+g3*sin(2*pi*f2*(t-t1)+phi3)
f1 is the fundamental frequency
f2=2*f1
f3=2*f2
The amplitudes g1, g2 and g3 are positive since the phases phi1, phi2 and phi3 vary from 0 to 2*pi.
The fundamental period will be calculated in two steps with a final accuracy of 10 days.
A smoothed RSI [bold black line] is analysed in the following example:
Paste in an Indicator Builder the
// Elementary Fourier analysis, by D. Tsokakis, May 2004
t=Cum(1)-1;
C1=MA(RSI(50),100);
start=Cum(IsTrue(C1))==1;
t1=ValueWhen(start,t);
PlotShapes(shapeDownTriangle*start,colorYellow);
C10=ValueWhen(start,C1);Plot(C1,"C1",colorBlack,8);
GraphXSpace=2;
x = Cum(1);
lastx = LastValue( x );
Daysback = LastValue(Cum(IsTrue(C1)));
aa = LastValue( LinRegIntercept( C1, Daysback) );
bb = LastValue( LinRegSlope( C1, Daysback ) );
yy = Aa + bb * ( x - (Lastx - DaysBack) );
yy=IIf( x >= (lastx - Daysback), yy, -1e10 );
Plot( yy, "yy", colorRed );
detrend=C1-yy;
new1=detrend;Hor=LastValue(Cum(new1)/Cum(IsTrue(C1)));
pi=4*atan(1);n=12;
// Fundamental period, crude approximation
error00=10000;per01=0;g01=0;phi01=0;stg0=0.5;stp0=100;
for(phi=0;phi<2*pi;phi=phi+pi/n)
{
for(g=0.5;g<=8;g=g+stg0)
{
for(per=300;per<=1000;per=per+stp0)
{f=1/per;
y=Hor+g*sin(2*pi*f*(t-t1)+phi);
error=LastValue(Cum(abs(y-new1)));
if(error<error00)
{error00=error;per01=per;g01=g;phi01=phi;}
}}}
f01=1/per01;y01=Hor+g01*sin(2*pi*f01*(t-t1)+phi01);
Plot(y01+yy,"y01",colorBlack,1);
Title=Name()+" [ Sample="+WriteVal(Daysback,1.0)+" bars ]"+"\nyS0="+WriteVal(Hor,1.2)+
"\nyS01="+
WriteVal(g01,1.1)+"*sin(2*pi*(1/"+
WriteVal(per01,1.0)+")*(t-t1)+"+
WriteVal(12*phi01/pi,1.0)+"*pi/"+WriteVal(n,1.0)+"), Error1 ="+
WriteVal(LastValue(Cum(abs(y01-new1))),1.0)+", Error1/bar ="+
WriteVal(2*LastValue(Cum(abs(y01-new1)))/Daysback,1.2)+" %";;
// Fundamental period, detailed approximation
error0=10000;per1=0;g1=0;phi1=0;stg=0.5;stp=10;
for(phi=0;phi<2*pi;phi=phi+pi/n)
{
for(g=0.5;g<=8;g=g+stg)
{
for(per=per01-stp0;per<=per01+stp0;per=per+stp)
{f=1/per;
y=Hor+g*sin(2*pi*f*(t-t1)+phi);
error=LastValue(Cum(abs(y-new1)));
if(error<error0)
{error0=error;per1=per;g1=g;phi1=phi;}
}}}
f1=1/per1;y1=Hor+g1*sin(2*pi*f1*(t-t1)+phi1);
Plot(y1+yy,"y1",colorYellow,1);
Title=Title+
"\nyS1="+
WriteVal(g1,1.1)+"*sin(2*pi*(1/"+
WriteVal(per1,1.0)+")*(t-t1)+"+
WriteVal(12*phi1/pi,1.0)+"*pi/"+WriteVal(n,1.0)+"), Error1 ="+
WriteVal(LastValue(Cum(abs(y1-new1))),1.0)+", Error1/bar ="+
WriteVal(2*LastValue(Cum(abs(y1-new1)))/Daysback,1.2)+" %";;
// 2nd Harmonic
error0=10000;
for(phi=0;phi<2*pi;phi=phi+pi/n)
{
for(g=0;g<=8;g=g+0.1)
{
per2=per1/2;f=1/per2;
y2=y1+g*sin(2*pi*f*(t-t1)+phi);
error2=LastValue(Cum(abs(y2-new1)));
if(error2<error0)
{error0=error2;g2=g;phi2=phi;}
}}
f2=1/per2;y2=y1+g2*sin(2*pi*f2*(t-t1)+phi2);
Plot(y2+yy,"y1",colorBlue,1);
Title=Title+
"\nyS2="+
WriteVal(g2,1.1)+"*sin(2*pi*(1/"+
WriteVal(per2,1.0)+")*(t-t1)+"+
WriteVal(12*phi2/pi,1.0)+"*pi/"+WriteVal(n,1.0)+"), Error2 ="+
WriteVal(LastValue(Cum(abs(y2-new1))),1.0)+", Error2/bar ="+
WriteVal(2*LastValue(Cum(abs(y2-new1)))/Daysback,1.2)+" %";;
// 3rd Harmonic
error0=10000;
for(phi=0;phi<2*pi;phi=phi+pi/n)
{
for(g=0;g<=8;g=g+0.1)
{
per3=per2/2;f=1/per3;
y3=y2+g*sin(2*pi*f*(t-t1)+phi);
error3=LastValue(Cum(abs(y3-new1)));
if(error3<error0)
{error0=error3;g3=g;phi3=phi;}
}}
f3=1/per3;y3=y2+g3*sin(2*pi*f3*(t-t1)+phi3);
Plot(y3+yy,"y1",colorWhite,8);
Title=Title+
"\nyS3="+
WriteVal(g3,1.1)+"*sin(2*pi*(1/"+
WriteVal(per3,1.0)+")*(t-t1)+"+
WriteVal(12*phi3/pi,1.0)+"*pi/"+WriteVal(n,1.0)+"), Error3 ="+
WriteVal(LastValue(Cum(abs(y3-new1))),1.0)+", Error3/bar ="+
WriteVal(2*LastValue(Cum(abs(y3-new1)))/Daysback,1.2)+" %";
The bold white line is the final result.
Quote from mmillar:
John Ehlers' mission in life is to tell people how crap FFT is. But obviously not everyone is listening.
http://www.mesasoftware.com/#FFT Comparison
Quote from Baruch:
Well, it seems a little bit complicated?
Quote from TSOKAKIS:
What is complicated, the concept or the code ?
The concept, ie the sinusoidal analysis of a non-periodic function is quite common in theoretical and applied maths/engineering etc
The code is not bad, some friend may give a shorter one via C++ translation [if he comes to some result, I will let you know...]
Using Amibroker 4.50 in a PIII/800, 64MB RAM, it takes ~8sec for a 1000bar history.
FFT is quite faster but not that accurate.
Quote from Baruch:
Oh, so simple?
Quote from TSOKAKIS:
An oscillator array y may have a linear trend yL.
After the linear detrending, the new y-yL may be analysed into a sum of sinusoidal terms.
y-yL=g1*sin(2*pi*f1*(t-t1)+phi1)+g2*sin(2*pi*f2*(t-t1)+phi2)+...
We shall examine here the result of an elementary Fourier analysis fundamental frequency and its 2nd and 3rd harmonics
y=yL+g1*sin(2*pi*f1*(t-t1)+phi1)+g2*sin(2*pi*f2*(t-t1)+phi2)+g3*sin(2*pi*f2*(t-t1)+phi3)
f1 is the fundamental frequency
f2=2*f1
f3=2*f2
The amplitudes g1, g2 and g3 are positive since the phases phi1, phi2 and phi3 vary from 0 to 2*pi.
The fundamental period will be calculated in two steps with a final accuracy of 10 days.
A smoothed RSI [bold black line] is analysed in the following example:
Paste in an Indicator Builder the
// Elementary Fourier analysis, by D. Tsokakis, May 2004
t=Cum(1)-1;
C1=MA(RSI(50),100);
start=Cum(IsTrue(C1))==1;
t1=ValueWhen(start,t);
PlotShapes(shapeDownTriangle*start,colorYellow);
C10=ValueWhen(start,C1);Plot(C1,"C1",colorBlack,8);
GraphXSpace=2;
x = Cum(1);
lastx = LastValue( x );
Daysback = LastValue(Cum(IsTrue(C1)));
aa = LastValue( LinRegIntercept( C1, Daysback) );
bb = LastValue( LinRegSlope( C1, Daysback ) );
yy = Aa + bb * ( x - (Lastx - DaysBack) );
yy=IIf( x >= (lastx - Daysback), yy, -1e10 );
Plot( yy, "yy", colorRed );
detrend=C1-yy;
new1=detrend;Hor=LastValue(Cum(new1)/Cum(IsTrue(C1)));
pi=4*atan(1);n=12;
// Fundamental period, crude approximation
error00=10000;per01=0;g01=0;phi01=0;stg0=0.5;stp0=100;
for(phi=0;phi<2*pi;phi=phi+pi/n)
{
for(g=0.5;g<=8;g=g+stg0)
{
for(per=300;per<=1000;per=per+stp0)
{f=1/per;
y=Hor+g*sin(2*pi*f*(t-t1)+phi);
error=LastValue(Cum(abs(y-new1)));
if(error<error00)
{error00=error;per01=per;g01=g;phi01=phi;}
}}}
f01=1/per01;y01=Hor+g01*sin(2*pi*f01*(t-t1)+phi01);
Plot(y01+yy,"y01",colorBlack,1);
Title=Name()+" [ Sample="+WriteVal(Daysback,1.0)+" bars ]"+"\nyS0="+WriteVal(Hor,1.2)+
"\nyS01="+
WriteVal(g01,1.1)+"*sin(2*pi*(1/"+
WriteVal(per01,1.0)+")*(t-t1)+"+
WriteVal(12*phi01/pi,1.0)+"*pi/"+WriteVal(n,1.0)+"), Error1 ="+
WriteVal(LastValue(Cum(abs(y01-new1))),1.0)+", Error1/bar ="+
WriteVal(2*LastValue(Cum(abs(y01-new1)))/Daysback,1.2)+" %";;
// Fundamental period, detailed approximation
error0=10000;per1=0;g1=0;phi1=0;stg=0.5;stp=10;
for(phi=0;phi<2*pi;phi=phi+pi/n)
{
for(g=0.5;g<=8;g=g+stg)
{
for(per=per01-stp0;per<=per01+stp0;per=per+stp)
{f=1/per;
y=Hor+g*sin(2*pi*f*(t-t1)+phi);
error=LastValue(Cum(abs(y-new1)));
if(error<error0)
{error0=error;per1=per;g1=g;phi1=phi;}
}}}
f1=1/per1;y1=Hor+g1*sin(2*pi*f1*(t-t1)+phi1);
Plot(y1+yy,"y1",colorYellow,1);
Title=Title+
"\nyS1="+
WriteVal(g1,1.1)+"*sin(2*pi*(1/"+
WriteVal(per1,1.0)+")*(t-t1)+"+
WriteVal(12*phi1/pi,1.0)+"*pi/"+WriteVal(n,1.0)+"), Error1 ="+
WriteVal(LastValue(Cum(abs(y1-new1))),1.0)+", Error1/bar ="+
WriteVal(2*LastValue(Cum(abs(y1-new1)))/Daysback,1.2)+" %";;
// 2nd Harmonic
error0=10000;
for(phi=0;phi<2*pi;phi=phi+pi/n)
{
for(g=0;g<=8;g=g+0.1)
{
per2=per1/2;f=1/per2;
y2=y1+g*sin(2*pi*f*(t-t1)+phi);
error2=LastValue(Cum(abs(y2-new1)));
if(error2<error0)
{error0=error2;g2=g;phi2=phi;}
}}
f2=1/per2;y2=y1+g2*sin(2*pi*f2*(t-t1)+phi2);
Plot(y2+yy,"y1",colorBlue,1);
Title=Title+
"\nyS2="+
WriteVal(g2,1.1)+"*sin(2*pi*(1/"+
WriteVal(per2,1.0)+")*(t-t1)+"+
WriteVal(12*phi2/pi,1.0)+"*pi/"+WriteVal(n,1.0)+"), Error2 ="+
WriteVal(LastValue(Cum(abs(y2-new1))),1.0)+", Error2/bar ="+
WriteVal(2*LastValue(Cum(abs(y2-new1)))/Daysback,1.2)+" %";;
// 3rd Harmonic
error0=10000;
for(phi=0;phi<2*pi;phi=phi+pi/n)
{
for(g=0;g<=8;g=g+0.1)
{
per3=per2/2;f=1/per3;
y3=y2+g*sin(2*pi*f*(t-t1)+phi);
error3=LastValue(Cum(abs(y3-new1)));
if(error3<error0)
{error0=error3;g3=g;phi3=phi;}
}}
f3=1/per3;y3=y2+g3*sin(2*pi*f3*(t-t1)+phi3);
Plot(y3+yy,"y1",colorWhite,8);
Title=Title+
"\nyS3="+
WriteVal(g3,1.1)+"*sin(2*pi*(1/"+
WriteVal(per3,1.0)+")*(t-t1)+"+
WriteVal(12*phi3/pi,1.0)+"*pi/"+WriteVal(n,1.0)+"), Error3 ="+
WriteVal(LastValue(Cum(abs(y3-new1))),1.0)+", Error3/bar ="+
WriteVal(2*LastValue(Cum(abs(y3-new1)))/Daysback,1.2)+" %";
The bold white line is the final result.