Measuring Cycle Period
The Measuring Cycle Period AFL in Amibroker assists traders in identifying and measuring cyclical patterns within market data. Utilizing amibroker data feed capabilities enables the identification of periodicity in market movements. This AFL aids traders in understanding cycle durations, assisting in better-timed entries or exits based on cyclical patterns.
/ "Filters are tuned to 8,9,10,...,50 periods. The filter with the highest output represents the dominant cycle. Implementing the idea presented in the article is easy using the AmiBroker Formula Language. "; 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", colorRed ); Plot( Value2, "Cosine", colorGreen ); } GraphZOrder = 1;