FUNCTION |
The function performs FFT (Fast Fourier Transform) on last 'len' bars of the array, if len is set to zero, then FFT is performed on entire array. len parameter must be even.
Result:
function returns array which holds FFT bins for first 'len' bars. There are len/2 FFT complex bins returned,
where bin is a pair of numbers (complex number): first is real part of the complex number and second number
is the imaginary part of the complex number.
result = FFT( array, 256 );
where:
- 0th bin (result[0] and result[1]) represents DC component,
- 1st bin (result[1 ] and result[2]) represents real and imaginary parts of lowest frequency range
and so on upto result[ len - 2 ] and result[ len - 1 ]
remaining elements of the array are set to zero.
IMPORTANT note: input array for FFT must NOT contain any Null values. Use Nz() function to convert Nulls to zeros if you are not sure that input array is free from nulls.
FFT bins are complex numbers and do not represent real amplitude and phase. To obtain amplitude and
phase from bins you need to convert inside the formula. The following code snipplet does that:
ffc = FFT(data,Len);
for( i = 0;
i < Len - 1; i = i + 2 )
{
amp[ i ] = amp[ i + 1 ]
= sqrt(ffc[ i ]^ 2 + ffc[
i + 1 ]^2);
phase[ i ] = phase[ i + 1 ]
= atan2( ffc[ i + 1],
ffc[ i ] );
}
|
EXAMPLE |
SetBarsRequired(100000,100000);
Len = Param("FFT
Length", 1024, 64, 10000, 10 );
Len = Min( Len, BarCount );
x = BarIndex();
x1 = x - BarCount +
Len;
input = C;
a = LastValue( LinRegIntercept(
input, Len - 1 ) );
b = LastValue( LinRegSlope(
input, Len - 1 ) );
Lr = a + b * x1;
data = input - Lr;// de-trending
ffc = FFT(data,Len);
for( i = 0;
i < Len - 1; i = i + 2 )
{
amp[ i ] = amp[ i + 1 ]
= sqrt(ffc[ i ]^ 2 + ffc[
i + 1 ]^2);
phase[ i ] = phase[ i + 1 ]
= atan2( ffc[ i + 1],
ffc[ i ] );
}
auto = ParamToggle("Auto
dominant cycle", "No|Yes", 1 );
sbar = Param( "Which
FFT bin", 1, 0, 50 );
skipbin1 = ParamToggle("Skip
1st FFT bin", "No|Yes", 1 );
if( auto )
{
sbar = int( LastValue(ValueWhen(
amp == LastValue(Highest( IIf(
skipbin1 AND x < 4, 0 ,
amp ) )), x / 2 )) );
}
fv = Status("firstvisiblebar");
thisbar = Ref( int(x/2)
== sbar, -fv);
Plot( Ref(amp,-fv),
"amplitude (bin " + Ref( int(x/2),
-fv ) +")", IIf(
thisbar, colorRed, colorBlack ),styleArea);
Plot( IIf( BarCount - BarIndex() < Len,
data, Null ) ,
"de-trended input ("+Len+" bars)", colorOrange, styleLeftAxisScale );
Plot( cos(
phase[ sbar * 2 ] + (sbar)
* x1 * 2 * 3.1415926 /
Len ),
" dominant cycle "+ Len/(sbar)
+ "(" + sbar + " bin)
bars", colorBlue, styleOwnScale );
GraphZOrder=1;
GraphXSpace = 10;
|