Sidebar for the article “Past Market Cycles” by John F. Ehlers, in the September 2016 issue of Technical Analysis of STOCKS & COMMODITIES magazine.
Inputs: EnhanceResolution(False); Vars: AvgLength(3), M(0), N(0), X(0), Y(0), alpha1(0), HP(0), a1(0), b1(0), c1(0), c2(0), c3(0), Filt(0), Lag(0), count(0), Sx(0), Sy(0), Sxx(0), Syy(0), Sxy(0), Period(0), Sp(0), Spx(0), MaxPwr(0), PeakPwr(0), DominantCycle(0), Color1(0), Color2(0), Color3(0); Arrays: Corr[70](0), CosinePart[70](0), SinePart[70](0), SqSum[70](0), R[70, 2](0), Pwr[70](0); //Highpass Filter and SuperSmoother Filter together form a Roofing Filter //Highpass Filter alpha1 = (1 - Sine (360 / 48)) / Cosine(360 / 48); HP = .5*(1 + alpha1)*(Close - Close[1]) + alpha1*HP[1]; //Smooth with a SuperSmoother Filter a1 = expvalue(-1.414*3.14159 / 8); b1 = 2*a1*Cosine(1.414*180 / 8); c2 = b1; c3 = -a1*a1; c1 = 1 - c2 - c3; Filt = c1*(HP + HP[1]) / 2 + c2*Filt[1] + c3*Filt[2]; //Pearson correlation for each value of lag For Lag = 0 to 48 Begin //Set the averaging length as M M = AvgLength; If AvgLength = 0 Then M = Lag; Sx = 0; Sy = 0; Sxx = 0; Syy = 0; Sxy = 0; For count = 0 to M - 1 Begin X = Filt[count]; Y = Filt[Lag + count]; Sx = Sx + X; Sy = Sy + Y; Sxx = Sxx + X*X; Sxy = Sxy + X*Y; Syy = Syy + Y*Y; End; If (M*Sxx - Sx*Sx)*(M*Syy - Sy*Sy) > 0 Then Corr[Lag] = (M*Sxy - Sx*Sy)/SquareRoot((M*Sxx - Sx*Sx)*(M*Syy - Sy*Sy)); End; //Compute the Fourier Transform for each Correlation For Period = 8 to 48 Begin CosinePart[Period] = 0; SinePart[Period] = 0; For N = 3 to 48 Begin CosinePart[Period] = CosinePart[Period] + Corr[N]*Cosine(360*N / Period); SinePart[Period] = SinePart[Period] + Corr[N]*Sine(360*N / Period); End; SqSum[Period] = CosinePart[Period]*CosinePart[Period] + SinePart[Period]*SinePart[Period]; End; For Period = 8 to 48 Begin R[Period, 2] = R[Period, 1]; R[Period, 1] = .2*SqSum[Period]*SqSum[Period] + .8*R[Period, 2]; End; //Find Maximum Power Level for Normalization MaxPwr = 0; For Period = 8 to 48 Begin If R[Period, 1] > MaxPwr Then MaxPwr = R[Period, 1]; End; For Period = 8 to 48 Begin Pwr[Period] = R[Period, 1] / MaxPwr; End; //Optionally increase Display Resolution by raising the NormPwr to a higher mathematically power (since the maximum amplitude is unity, cubing all amplitudes further reduces the smaller ones). If EnhanceResolution = True Then Begin For Period = 8 to 48 Begin Pwr[Period] = Power(Pwr[Period], 3); End; End; //Compute the dominant cycle using the CG of the spectrum DominantCycle = 0; PeakPwr = 0; For Period = 8 to 48 Begin If Pwr[Period] > PeakPwr Then PeakPwr = Pwr[Period]; End; Spx = 0; Sp = 0; For Period = 8 to 48 Begin If PeakPwr >= .25 and Pwr[Period] >= .25 Then Begin Spx = Spx + Period*Pwr[Period]; Sp = Sp + Pwr[Period]; End; End; If Sp <> 0 Then DominantCycle = Spx / Sp; If Sp < .25 Then DominantCycle = DominantCycle[1]; //Plot as a Heatmap Color3 = 0; For Period = 8 to 48 Begin If Pwr[Period] > .5 Then Begin Color1 = 255; Color2 = 255*(2*Pwr[Period] - 1); End Else Begin Color1 = 2*255*Pwr[Period]; Color2 = 0; End; If Period = 8 Then Plot8[0](8, "S8", RGB(Color1, Color2, Color3),0,4); If Period = 9 Then Plot9[0](9, "S9", RGB(Color1, Color2, Color3),0,4); If Period = 10 Then Plot10[0](10, "S10", RGB(Color1, Color2, Color3),0,4); If Period = 11 Then Plot11[0](11, "S11", RGB(Color1, Color2, Color3),0,4); If Period = 12 Then Plot12[0](12, "S12", RGB(Color1, Color2, Color3),0,4); If Period = 13 Then Plot13[0](13, "S13", RGB(Color1, Color2, Color3),0,4); If Period = 14 Then Plot14[0](14, "S14", RGB(Color1, Color2, Color3),0,4); If Period = 15 Then Plot15[0](15, "S15", RGB(Color1, Color2, Color3),0,4); If Period = 16 Then Plot16[0](16, "S16", RGB(Color1, Color2, Color3),0,4); If Period = 17 Then Plot17[0](17, "S17", RGB(Color1, Color2, Color3),0,4); If Period = 18 Then Plot18[0](18, "S18", RGB(Color1, Color2, Color3),0,4); If Period = 19 Then Plot19[0](19, "S19", RGB(Color1, Color2, Color3),0,4); If Period = 20 Then Plot20[0](20, "S20", RGB(Color1, Color2, Color3),0,4); If Period = 21 Then Plot21[0](21, "S21", RGB(Color1, Color2, Color3),0,4); If Period = 22 Then Plot22[0](22, "S22", RGB(Color1, Color2, Color3),0,4); If Period = 23 Then Plot23[0](23, "S23", RGB(Color1, Color2, Color3),0,4); If Period = 24 Then Plot24[0](24, "S24", RGB(Color1, Color2, Color3),0,4); If Period = 25 Then Plot25[0](25, "S25", RGB(Color1, Color2, Color3),0,4); If Period = 26 Then Plot26[0](26, "S26", RGB(Color1, Color2, Color3),0,4); If Period = 27 Then Plot27[0](27, "S27", RGB(Color1, Color2, Color3),0,4); If Period = 28 Then Plot28[0](28, "S28", RGB(Color1, Color2, Color3),0,4); If Period = 29 Then Plot29[0](29, "S29", RGB(Color1, Color2, Color3),0,4); If Period = 30 Then Plot30[0](30, "S30", RGB(Color1, Color2, Color3),0,4); If Period = 31 Then Plot31[0](31, "S31", RGB(Color1, Color2, Color3),0,4); If Period = 32 Then Plot32[0](32, "S32", RGB(Color1, Color2, Color3),0,4); If Period = 33 Then Plot33[0](33, "S33", RGB(Color1, Color2, Color3),0,4); If Period = 34 Then Plot34[0](34, "S34", RGB(Color1, Color2, Color3),0,4); If Period = 35 Then Plot35[0](35, "S35", RGB(Color1, Color2, Color3),0,4); If Period = 36 Then Plot36[0](36, "S36", RGB(Color1, Color2, Color3),0,4); If Period = 37 Then Plot37[0](37, "S37", RGB(Color1, Color2, Color3),0,4); If Period = 38 Then Plot38[0](38, "S38", RGB(Color1, Color2, Color3),0,4); If Period = 39 Then Plot39[0](39, "S39", RGB(Color1, Color2, Color3),0,4); If Period = 40 Then Plot40[0](40, "S40", RGB(Color1, Color2, Color3),0,4); If Period = 41 Then Plot41[0](41, "S41", RGB(Color1, Color2, Color3),0,4); If Period = 42 Then Plot42[0](42, "S42", RGB(Color1, Color2, Color3),0,4); If Period = 43 Then Plot43[0](43, "S43", RGB(Color1, Color2, Color3),0,4); If Period = 44 Then Plot44[0](44, "S44", RGB(Color1, Color2, Color3),0,4); If Period = 45 Then Plot45[0](45, "S45", RGB(Color1, Color2, Color3),0,4); If Period = 46 Then Plot46[0](46, "S46", RGB(Color1, Color2, Color3),0,4); If Period = 47 Then Plot47[0](47, "S47", RGB(Color1, Color2, Color3),0,4); If Period = 48 Then Plot48[0](48, "S48", RGB(Color1, Color2, Color3),0,4); End;