"Measuring Cycle Periods",John Ehlers presents a very interesting technique of measuring dominant market cycle periods by means of multiple bandpass filtering. By utilizing an approach similar to audio equalizers, the signal (here, the price series) is fed into a set of simple second-order infinite impulse response bandpass filters.

Filters are tuned to 8,9,10,...,50 periods. The filter with the highest output represents the dominant cycle.

- traders.com march2008 traders tips

below is the afl and the screenshot of SBIN 5min chart from 24.6.13 to 28.6.13.

interesting!the afl spotted the top&bottom several times very accurately!

PHP:

```
_SECTION_BEGIN("cycle121");
SetChartBkColor(ParamColor("Panel color ",colorOrange));
PI = 3.1415926;
Data = (H+L)/2;
// detrending ( high-pass filter )
HFPeriods = Param("HP filter cutoff", 40, 20, 100 );
alpha1 = ( 1-sin(2*pi/HFPeriods) ) / cos( 2 * pi / HFPeriods );
HP = AMA2( Data - Ref( Data, -1 ), 0.5 * ( 1 + alpha1 ), alpha1 );
// 6-tap low-pass FIR filter
SmoothHP = ( HP + 2 * Ref( HP, -1 ) + 3 * Ref( HP, -2 ) +
3 * Ref( HP, -3 ) + 2 * Ref( HP, -4 ) + Ref( HP, -5 ) )/12;
SmoothHPDiff = SmoothHP - Ref( SmoothHP, -1 );
x = BarIndex();
delta = -0.015 * x + 0.5;
delta = Max( delta, 0.15 );
Q = 0;
Real = 0;
Imag = 0;
Ampl = 0;
DB = 0;
I = SmoothHP;
MaxAmpl = 0;
for( N = 8; N <= 50; N++ )
{
beta = cos( 2 * PI / N );
Q = ( N / ( 2 * PI ) ) * SmoothHPDiff;
for( bar = 8; bar < BarCount; bar++ )
{
gamma = 1 / cos( 4 * PI * delta[ bar ] / N );
alpha = gamma - sqrt( gamma ^ 2 - 1 );
Real[ bar ] = 0.5 * ( 1 - alpha ) * ( I[ bar ] - I[ bar - 1 ] ) +
beta * ( 1 + alpha ) * Real[ bar - 1 ] -
alpha * Real[ bar - 2 ];
Imag[ bar ] = 0.5 * ( 1- alpha ) * ( Q[ bar ] - Q[ bar - 1 ] ) +
beta * ( 1 + alpha ) * Imag[ bar - 1 ] -
alpha * Imag[ bar - 2 ];
}
Ampl = Real ^ 2 + Imag ^ 2;
MaxAmpl = Max( MaxAmpl, Ampl );
VarSet("Ampl"+N, Ampl );
}
TunedFilterDisplay = ParamToggle("Dom Cycle Tuned Filter", "No|Yes" );
// Plot Heat Map ( Spectrogram )
// and find dominant cycle
DcNum = DcDenom = 0;
for( N = 8; N <= 50; N++ )
{
Ampl = VarGet("Ampl"+N);
db = Nz( -10 * log10( 0.01 / ( 1 - 0.99 * Ampl / MaxAmpl ) ) );
db = Min( db, 20 ) ;
Red = IIf( db <= 10, 255, 255 * ( 2 - db/10 ) );
Green = IIf( db <= 10, 255 * ( 1 - db/10 ), 0 );
if( NOT TunedFilterDisplay )
PlotOHLC( N, N, N-1, N-1, "", ColorRGB( Red, Green, 0 ),
styleCloud | styleNoLabel );
DcNum = DcNum + (db < 3 ) * N * ( 20 - db );
DcDenom = DcDenom + ( db < 3 ) * ( 20 - db );
}
DC = DcNum / DcDenom;
if( ParamToggle("Show Dom. Cycle?", "No|Yes" ) )
{
DomCycle = Median( DC, 10 );
Plot( DomCycle, "Dominant Cycle", colorBlue );
}
if( TunedFilterDisplay )
{
DomCycle = Median( DC, 10 );
DomCycle = Max( DomCycle, 8 );
Value = 0;
for( bar = 10; bar < BarCount; bar++ )
{
beta = cos( 2 * PI / domCycle[ bar ] );
gamma = 1 / cos( 4 * PI * delta[ bar ] / DomCycle[ bar ] );
alpha = gamma - sqrt( gamma ^ 2 - 1 );
Value[ bar ] = 0.5 * ( 1 - alpha ) * SmoothHPDiff[ bar ] +
beta * ( 1 + alpha ) * Value[ bar - 1 ] -
alpha * Value[ bar - 2 ];
}
Value2 = ( domCycle / ( 2 * PI ) ) * ( Value - Ref( Value, -1 ) );
Plot( Value, "Sine", colorBlue );
Plot( Value2, "Cosine", colorWhite );
}
GraphZOrder = 1;
_SECTION_END();
```