ChRSpectrum.efs, DCTunedBypassFilter.efs
File Name: ChRSpectrum.efs, DCTunedBypassFilter.efs
Description:
These studies are based on the March 2008 article, Measuring CyclePeriods, by John F. Ehlers.
Formula Parameters:
ChRSpectrum.efs
- Show Dominant Cycle: false
- Dominant Cycle Color: blue
- Dominant Cycle Size: 2
DCTunedBypassFilter.efs
- Sine Color: red
- Cosine Color: cyan
- Sine Thickness: 2
- Cosine Thickness: 2
Notes:
The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com.
Download File:
ChRSpectrum.efs
DCTunedBypassFilter.efs
EFS Code:
ChRSpectrum.efs
/*************************************** Provided By : eSignal (c) Copyright 2008 Description: Measuring Cycle Periods by John Ehlers Version 1.0 1/04/2008 Notes: * March 2008 Issue of Stocks and Commodities Magazine * Study requires version 8.0 or later. Formula Parameters: Default: Show Dominant Cycle false Dominant Cycle Color blue Dominant Cycle Size 2 *****************************************************************/ function preMain() { setStudyTitle("Channelized Receiver Spectrum "); setShowCursorLabel(false); setShowTitleParameters(false); // Dominant Cycle properties setPlotType(PLOTTYPE_CIRCLE, 51); setDefaultBarBgColor(Color.black, 0); var fp1 = new FunctionParameter("bShowDC", FunctionParameter.BOOLEAN); fp1.setName("Show Dominant Cycle"); fp1.setDefault(false); var fp2 = new FunctionParameter("nDC_color", FunctionParameter.COLOR); fp2.setName("Dominant Cycle Color"); fp2.setDefault(Color.blue); var fp3 = new FunctionParameter("nDC_thick", FunctionParameter.NUMBER); fp3.setName("Dominant Cycle Size"); fp3.setLowerLimit(1); fp3.setDefault(2); } // Global Variables var bVersion = null; // Version flag var bInit = false; // Initialization flag var xPrice = null; var xHP = null; var xCleanData = null; var aDB = new Array(51); var aReturn = new Array(52); // return array var nDelta = 0.1; var nBeta = 0; var nGamma = 0; var nAlpha = 0; var nMaxAmpl = 0; var nNum = 0; var nDenom = 0; var nDC = 0; var nDomCyc = 0; var aDC = new Array(10); var aQ = new Array(51); var aI = new Array(51); var aReal = new Array(51); var aOlderI = new Array(51); var aOldReal = new Array(51); var aOlderReal = new Array(51); var aImag = new Array(51); var aOldQ = new Array(51); var aOlderQ = new Array(51); var aOldImag = new Array(51); var aOlderImag = new Array(51); var aAmpl = new Array(51); var aOldI = new Array(51); var aOldAmpl = new Array(51); for (var j = 0; j < 51; j++) { aQ[j] = 0; aI[j] = 0; aReal[j] = 0; aOlderI[j] = 0; aOldReal[j] = 0; aOlderReal[j] = 0; aImag[j] = 0; aOldQ[j] = 0; aOlderQ[j] = 0; aOldImag[j] = 0; aOlderImag[j] = 0; aAmpl[j] = 0; aOldI[j] = 0; aOldAmpl[j] = 0; } function main(bShowDC, nDC_color, nDC_thick) { if (bVersion == null) bVersion = verify(); if (bVersion == false) return; var nPeriod = 0; var n = 0; var nMaxPwr = 0; var nNum = 0; var nDenom = 0; var nDominantCycle = 0; var Color1 = null; var Color2 = null; var nState = getBarState(); //Initialization if (bInit == false) { drawTextPixel(0, 0, " ", null, Color.lightgrey, Text.RELATIVETOTOP|Text.RELATIVETOLEFT, null, 12, "bkg"); setDefaultBarFgColor(nDC_color, 51); setDefaultBarThickness(nDC_thick, 51); xPrice = hl2(); xHP = efsInternal("calcHP", xPrice); xCleanData = efsInternal("calcCleanData", xHP, xPrice); // Smooth HP bInit = true; } if (nState == BARSTATE_NEWBAR) { aDC.pop(); aDC.unshift(nDC); } if (nState == BARSTATE_NEWBAR) { nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { aOlderI[nPeriod] = aOldI[nPeriod]; aOldI[nPeriod] = aI[nPeriod]; aOlderQ[nPeriod] = aOldQ[nPeriod]; aOldQ[nPeriod] = aQ[nPeriod]; aOlderReal[nPeriod] = aOldReal[nPeriod]; aOldReal[nPeriod] = aReal[nPeriod]; aOlderImag[nPeriod] = aOldImag[nPeriod]; aOldImag[nPeriod] = aImag[nPeriod]; aOldAmpl[nPeriod] = aAmpl[nPeriod]; } } var nHP = xHP.getValue(0); var nCleanData = xCleanData.getValue(-50); if (nHP == null || nCleanData == null) return; nDelta = -.015 * getCurrentBarCount() + .5; if (nDelta < .15 ) { nDelta = .15; } if (getCurrentBarCount() > 6 ) { nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { nBeta = Math.cos((2*Math.PI)/nPeriod); nGamma = 1 / Math.cos((((2*Math.PI)+(2*Math.PI)) * nDelta) / nPeriod); nAlpha = nGamma - Math.sqrt(nGamma*nGamma - 1); aQ[nPeriod] = (nPeriod / 6.283185)*(xCleanData.getValue(0) - xCleanData.getValue(-1)); aI[nPeriod] = xCleanData.getValue(0); aReal[nPeriod] = .5*(1 - nAlpha)*(aI[nPeriod] - aOlderI[nPeriod]) + nBeta*(1 + nAlpha)*aOldReal[nPeriod] - nAlpha*aOlderReal[nPeriod]; aImag[nPeriod] = .5*(1 - nAlpha)*(aQ[nPeriod] - aOlderQ[nPeriod]) + nBeta*(1 + nAlpha)*aOldImag[nPeriod] - nAlpha*aOlderImag[nPeriod]; aAmpl[nPeriod] = (aReal[nPeriod]*aReal[nPeriod] + aImag[nPeriod]*aImag[nPeriod]); } } nMaxAmpl = aAmpl[10]; nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { if (aAmpl[nPeriod] > nMaxAmpl) { nMaxAmpl = aAmpl[nPeriod]; } } nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { if (nMaxAmpl != 0 && (aAmpl[nPeriod] / nMaxAmpl) > 0 ) { aDB[nPeriod] = -10 * Math.log(.01 / (1 - .99*aAmpl[nPeriod] / nMaxAmpl)) / Math.log(10); } if (aDB[nPeriod] > 20 ) { aDB[nPeriod] = 20; } } nNum = 0; nDemon = 0; nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { if (aDB[nPeriod] <= 3 ) { nNum = nNum + nPeriod*(20 - aDB[nPeriod]); nDenom = nDenom + (20 - aDB[nPeriod]); } if (nDenom != 0 ) { nDC = nNum / nDenom; aDC[0] = nDC; } } nDomCyc = Median(aDC, 10); if (bShowDC == true) { aReturn[51] = nDomCyc; } //Plot the Spectrum as a Heatmap nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { if (aDB[nPeriod] <= 10) { Color1 = 255; Color2 = Math.round(255*(1 - aDB[nPeriod]/10)); } if (aDB[nPeriod] > 10) { Color1 = Math.round(255*(2 - aDB[nPeriod]/10)); Color2 = 0; } aReturn[nPeriod] = nPeriod; setDefaultBarFgColor(Color.RGB(Color1 , Color2, 0), nPeriod); setDefaultBarThickness(4, nPeriod); } // aReturn[51] // contains the Dominant Cycle value return aReturn; } // calcHP globals var nPrevHP = null; var nCurrHP = null; function calcHP(x) { var nAlpha1 = (1 - Math.sin((2*Math.PI)/40)) / Math.cos((2*Math.PI)/40); var nHP = null; if (getCurrentBarCount() <= 5 ) { nCurrHP = x.getValue(0); return nCurrHP; } else { if (x.getValue(-1) == null) return null; if (getBarState() == BARSTATE_NEWBAR) nPrevHP = nCurrHP; nCurrHP = ( 0.5*(1 + nAlpha1)*(x.getValue(0) - x.getValue(-1)) + nAlpha1*nPrevHP ); return nCurrHP; } } function calcCleanData(x, xP) { //SmoothHP if (getCurrentBarCount() == 1 ) { return 0; } else if (getCurrentBarCount() <= 7 ) { return xP.getValue(0) - xP.getValue(-1); } else { return ( x.getValue(0) + 2*x.getValue(-1) + 3*x.getValue(-2) + 3*x.getValue(-3) + 2*x.getValue(-4) + x.getValue(-5) ) / 12; } } function Median(myArray, Length) { var aArray = new Array(Length); var nMedian = null; for (var i = 0; i < Length; i++) { aArray[i] = myArray[i]; } aArray = aArray.sort(compareNumbers); nMedian = aArray[Math.round((Length-1)/2)]; return nMedian; } function compareNumbers(a, b) { return a - b } function verify() { var b = false; if (getBuildNumber() < 779) { drawTextAbsolute(5, 35, "This study requires version 8.0 or later.", Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT, null, 13, "error"); drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp", Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT, null, 13, "upgrade"); return b; } else { b = true; } return b; }
DCTunedBypassFilter.efs
/*************************************** Provided By : eSignal (c) Copyright 2008 Description: Measuring Cycle Periods by John Ehlers Version 1.0 1/04/2008 Notes: * March 2008 Issue of Stocks and Commodities Magazine * Study requires version 8.0 or later. Formula Parameters: Default: Sine Color red Cosine Color cyan Sine Thickness 2 Cosine Thickness 2 *****************************************************************/ function preMain() { setStudyTitle("Dominant Cycle Tuned Bypass Filter "); setShowTitleParameters(false); setCursorLabelName("Sine", 0); setCursorLabelName("Cosine", 1); var fp1 = new FunctionParameter("nS_color", FunctionParameter.COLOR); fp1.setName("Sine Color"); fp1.setDefault(Color.red); var fp2 = new FunctionParameter("nC_color", FunctionParameter.COLOR); fp2.setName("Cosine Color"); fp2.setDefault(Color.cyan); var fp3 = new FunctionParameter("nS_thick", FunctionParameter.NUMBER); fp3.setName("Sine Thickness"); fp3.setLowerLimit(1); fp3.setDefault(2); var fp4 = new FunctionParameter("nC_thick", FunctionParameter.NUMBER); fp4.setName("Cosine Thickness"); fp4.setLowerLimit(1); fp4.setDefault(2); } // Global Variables var bVersion = null; // Version flag var bInit = false; // Initialization flag var xPrice = null; var xHP = null; var xCleanData = null; var aDB = new Array(51); var nDelta = 0.1; var nBeta = 0; var nGamma = 0; var nAlpha = 0; var nMaxAmpl = 0; var nNum = 0; var nDenom = 0; var nDC = 0; var nDomCyc = 0; var nValue1 = null; var nValue1_1 = null; var nValue1_2 = null; var nValue2 = null; var aDC = new Array(10); var aQ = new Array(51); var aI = new Array(51); var aReal = new Array(51); var aOlderI = new Array(51); var aOldReal = new Array(51); var aOlderReal = new Array(51); var aImag = new Array(51); var aOldQ = new Array(51); var aOlderQ = new Array(51); var aOldImag = new Array(51); var aOlderImag = new Array(51); var aAmpl = new Array(51); var aOldI = new Array(51); var aOldAmpl = new Array(51); for (var j = 0; j < 51; j++) { aQ[j] = 0; aI[j] = 0; aReal[j] = 0; aOlderI[j] = 0; aOldReal[j] = 0; aOlderReal[j] = 0; aImag[j] = 0; aOldQ[j] = 0; aOlderQ[j] = 0; aOldImag[j] = 0; aOlderImag[j] = 0; aAmpl[j] = 0; aOldI[j] = 0; aOldAmpl[j] = 0; } function main(nS_color, nC_color, nS_thick, nC_thick) { if (bVersion == null) bVersion = verify(); if (bVersion == false) return; var nPeriod = 0; var n = 0; var nMaxPwr = 0; var nNum = 0; var nDenom = 0; var nDominantCycle = 0; var Color1 = null; var Color2 = null; var nState = getBarState(); //Initialization if (bInit == false) { setDefaultBarFgColor(nS_color, 0); setDefaultBarFgColor(nC_color, 1); setDefaultBarThickness(nS_thick, 0); setDefaultBarThickness(nC_thick, 1); xPrice = hl2(); xHP = efsInternal("calcHP", xPrice); xCleanData = efsInternal("calcCleanData", xHP, xPrice); // Smooth HP bInit = true; } if (nState == BARSTATE_NEWBAR) { aDC.pop(); aDC.unshift(nDC); nValue1_2 = nValue1_1; nValue1_1 = nValue1; } if (nState == BARSTATE_NEWBAR) { nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { aOlderI[nPeriod] = aOldI[nPeriod]; aOldI[nPeriod] = aI[nPeriod]; aOlderQ[nPeriod] = aOldQ[nPeriod]; aOldQ[nPeriod] = aQ[nPeriod]; aOlderReal[nPeriod] = aOldReal[nPeriod]; aOldReal[nPeriod] = aReal[nPeriod]; aOlderImag[nPeriod] = aOldImag[nPeriod]; aOldImag[nPeriod] = aImag[nPeriod]; aOldAmpl[nPeriod] = aAmpl[nPeriod]; } } var nHP = xHP.getValue(0); var nCleanData = xCleanData.getValue(-50); if (nHP == null || nCleanData == null) return; nDelta = -.015 * getCurrentBarCount() + .5; if (nDelta < .15 ) { nDelta = .15; } if (getCurrentBarCount() > 6 ) { nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { nBeta = Math.cos((2*Math.PI)/nPeriod); nGamma = 1 / Math.cos((((2*Math.PI)+(2*Math.PI)) * nDelta) / nPeriod); nAlpha = nGamma - Math.sqrt(nGamma*nGamma - 1); aQ[nPeriod] = (nPeriod / 6.283185)*(xCleanData.getValue(0) - xCleanData.getValue(-1)); aI[nPeriod] = xCleanData.getValue(0); aReal[nPeriod] = .5*(1 - nAlpha)*(aI[nPeriod] - aOlderI[nPeriod]) + nBeta*(1 + nAlpha)*aOldReal[nPeriod] - nAlpha*aOlderReal[nPeriod]; aImag[nPeriod] = .5*(1 - nAlpha)*(aQ[nPeriod] - aOlderQ[nPeriod]) + nBeta*(1 + nAlpha)*aOldImag[nPeriod] - nAlpha*aOlderImag[nPeriod]; aAmpl[nPeriod] = (aReal[nPeriod]*aReal[nPeriod] + aImag[nPeriod]*aImag[nPeriod]); } } nMaxAmpl = aAmpl[10]; nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { if (aAmpl[nPeriod] > nMaxAmpl) { nMaxAmpl = aAmpl[nPeriod]; } } nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { if (nMaxAmpl != 0 && (aAmpl[nPeriod] / nMaxAmpl) > 0 ) { aDB[nPeriod] = -10 * Math.log(.01 / (1 - .99*aAmpl[nPeriod] / nMaxAmpl)) / Math.log(10); } if (aDB[nPeriod] > 20 ) { aDB[nPeriod] = 20; } } nNum = 0; nDemon = 0; nPeriod = 8; for (nPeriod = 8; nPeriod <= 50; nPeriod++) { if (aDB[nPeriod] <= 3 ) { nNum = nNum + nPeriod*(20 - aDB[nPeriod]); nDenom = nDenom + (20 - aDB[nPeriod]); } if (nDenom != 0 ) { nDC = nNum / nDenom; aDC[0] = nDC; } } nDomCyc = Median(aDC, 10); if (nDomCyc < 8 ) { nDomCyc = 20; } nBeta = Math.cos((2*Math.PI)/nDomCyc); nGamma = 1 / Math.cos((((2*Math.PI)+(2*Math.PI)) * nDelta) / nDomCyc); nAlpha = nGamma - Math.sqrt(nGamma*nGamma - 1); nValue1 = .5*(1 - nAlpha)*(xCleanData.getValue(0) - xCleanData.getValue(-1)) + nBeta*(1 + nAlpha)*nValue1_1 - nAlpha*nValue1_2; nValue2 = (nDomCyc / 6.28)*(nValue1 - nValue1_1); return new Array(nValue1, nValue2); } // calcHP globals var nPrevHP = null; var nCurrHP = null; function calcHP(x) { var nAlpha1 = (1 - Math.sin((2*Math.PI)/40)) / Math.cos((2*Math.PI)/40); var nHP = null; if (getCurrentBarCount() <= 5 ) { nCurrHP = x.getValue(0); return nCurrHP; } else { if (x.getValue(-1) == null) return null; if (getBarState() == BARSTATE_NEWBAR) nPrevHP = nCurrHP; nCurrHP = ( 0.5*(1 + nAlpha1)*(x.getValue(0) - x.getValue(-1)) + nAlpha1*nPrevHP ); return nCurrHP; } } function calcCleanData(x, xP) { //SmoothHP if (getCurrentBarCount() == 1 ) { return 0; } else if (getCurrentBarCount() <= 7 ) { return xP.getValue(0) - xP.getValue(-1); } else { return ( x.getValue(0) + 2*x.getValue(-1) + 3*x.getValue(-2) + 3*x.getValue(-3) + 2*x.getValue(-4) + x.getValue(-5) ) / 12; } } function Median(myArray, Length) { var aArray = new Array(Length); var nMedian = null; for (var i = 0; i < Length; i++) { aArray[i] = myArray[i]; } aArray = aArray.sort(compareNumbers); nMedian = aArray[Math.round((Length-1)/2)]; return nMedian; } function compareNumbers(a, b) { return a - b } function verify() { var b = false; if (getBuildNumber() < 779) { drawTextAbsolute(5, 35, "This study requires version 8.0 or later.", Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT, null, 13, "error"); drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp", Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT, null, 13, "upgrade"); return b; } else { b = true; } return b; }