Here is this month's selection of Traders' Tips, contributed by various developers of technical analysis software to help readers more easily implement some of the strategies presented in this and other issues. November 2008
TRADERS' TIPSYou can copy these formulas and programs for easy use in your spreadsheet or analysis software. Simply "select" the desired text by highlighting as you would in any word processing program, then use your standard key command for copy or choose "copy" from the browser menu. The copied text can then be "pasted" into any open spreadsheet or other software by selecting an insertion point and executing a paste command. By toggling back and forth between an application window and the open Web page, data can be transferred with ease.
This month's tips include formulas and programs for:
TRADESTATION: CORONA CHARTS
WEALTH-LAB: CORONA CHARTS
eSIGNAL: CORONA CHARTS
AMIBROKER: CORONA CHARTS
NEUROSHELL TRADER: CORONA CHARTS
WORDEN BROTHERS BLOCKS: THE MIDAS TOUCH
AIQ: MOCS EXIT INDICATOR
TRADERSTUDIO: CORONA CHARTS
TRADE IDEAS: FADING THE MARKET
VT TRADER: GUPPY MULTIPLE MOVING AVERAGE (GMMA)
or return to November 2008 Contents
TRADESTATION: CORONA CHARTS
John Ehlers's corona indicators, as described in his article in this issue, "Corona Charts," provide a "multidimensional" view of market activity. See Figure 1 for a sample implementation.
EasyLanguage code for the studies was already provided by Ehlers for the article. To download this EasyLanguage code, go to the TradeStation and EasyLanguage Support Forum (https://www.tradestation.com/Discussions/forum.aspx?Forum_ID=213) and search for the file "CoronaCharts.Eld."
FIGURE 1: TRADESTATION, CORONA CHARTS AND ITS INDICATORS. Ehlers's corona indicators shown here are: cycle period, swing position, signal to noise ratio, and trend vigor. The left pane displays a 15-minute chart of the forex symbol EUR/USD. The right pane displays a 400-tick chart of the continuous 30-year bond futures contract.This article is for informational purposes. No type of trading or investment recommendation, advice or strategy is being made, given or in any manner provided by TradeStation Securities or its affiliates.--Mark MillsGO BACK
TradeStation Securities, Inc.
A subsidiary of TradeStation Group, Inc.
www.TradeStation.com
WEALTH-LAB: CORONA CHARTS
Even if you don't use corona charts for trading, you still might be able to impress someone with these colorful charts -- my spouse certainly was! We wrapped the indicator creation and plotting in a tidy SuperIndicators method so that all four indicators can be returned to a Strategy script in a single call. The full translation for Wealth-Lab 5 (.NET) WealthScript can be found in the STOCKS & COMMODITIES Traders' Tips section at the Wealth-Lab.com wiki site. A sample chart is shown in Figure 2.
FIGURE 2: WEALTH-LAB, CORONA CHART. The trend vigor's ominous corona in June 2008 provided a good warning that MSFT's March--April rally had lost its steam.WealthScript code (C#): using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; namespace WealthLab.Strategies { public class CoronaCharts : WealthScript { public const double twoPi = 2 * Math.PI; public const double fourPi = 4 * Math.PI; public class ArrayHolder { // current, old, older internal double I, I2, I3; internal double Q, Q2, Q3; internal double R, R2, R3; internal double Im, Im2, Im3; internal double A; internal double dB, dB2; } // Keep cntMax fifo samples and find the Highest and Lowest lead for samples in the list private void PhaseList(ref ArrayList fifo, int cntMax, double lead, out double H, out double L) { H = lead; L = lead; if( fifo.Count < cntMax ) fifo.Add(lead); else { fifo.RemoveAt(0); fifo.Add(lead); } for (int n = 0; n < fifo.Count - 1; n++) { double val = (double)fifo[n]; if( val > H ) H = val; if( val < L ) L = val; } } public void SuperIndicators(DataSeries ds, out DataSeries domCycMdn, out DataSeries snrSer, out DataSeries psnSer, out DataSeries tvSer) { // Initialize arrays ArrayHolder[] ah = new ArrayHolder[61]; for( int n = 12; n < 61; n++ ) ah[n] = new ArrayHolder(); double domCycle = 0d; string s = ds.Description + ")"; DataSeries[] DB = new DataSeries[61]; DataSeries domCyc = Close - Close; domCycMdn = domCyc * 0d; snrSer = domCycMdn + 0d; psnSer = snrSer + 0d; tvSer = psnSer + 0d; domCyc.Description = "DC(" + s; domCycMdn.Description = "DomCyc(" + s; snrSer.Description = "SNR(" + s; psnSer.Description = "Swing Position(" + s; tvSer.Description = "Trend Vigor(" + s; // Create and plot the decibel series - change the colors later ChartPane dbPane = CreatePane(40, false, false ); for( int n = 12; n < 61; n++ ) { double d = n / 2.0; DB[n] = domCyc + d; DB[n].Description = "Cycle." + d.ToString(); PlotSeries(dbPane, DB[n], Color.Black, LineStyle.Solid, 4); } DataSeries[] Raster = new DataSeries[51]; // SNR Corona chart ChartPane snrPane = CreatePane(40, false, false ); for( int n = 1; n < 51; n++ ) { double d = 1d + n / 5.0; Raster[n] = domCyc + d; Raster[n].Description = "SNR." + d.ToString(); PlotSeries(snrPane, Raster[n], Color.Black, LineStyle.Solid, 4); } DataSeries[] RasterSwg = new DataSeries[51]; // Swing Corona chart ChartPane swgPane = CreatePane(40, false, false ); for( int n = 1; n < 51; n++ ) { double d = 0.2 * n - 5.0; RasterSwg[n] = domCyc + d; RasterSwg[n].Description = "Swing." + d.ToString(); PlotSeries(swgPane, RasterSwg[n], Color.Black, LineStyle.Solid, 4); } DataSeries[] RasterTV = new DataSeries[51]; // Trend Vigor Corona chart ChartPane tvPane = CreatePane(40, false, false ); for( int n = 1; n < 51; n++ ) { double d = 0.4 * n - 10.0; RasterTV[n] = domCyc + d; RasterTV[n].Description = "TV." + d.ToString(); PlotSeries(tvPane, RasterTV[n], Color.Black, LineStyle.Solid, 4); } Color[] color = new Color[21]; // Convert decibels to RGB color for display for( int n = 0; n <= 10; n++ ) // yellow to red: 0 to 10 dB color[n] = Color.FromArgb(255, (int)(255 - (255 * n / 10)), 0); for( int n = 11; n <= 20; n++ ) // red to black: 11 to 20 db color[n] = Color.FromArgb( (int)(255 * (20 - n)/10 ), 0, 0); Color[] colorSNR = new Color[21]; // Corona chart SNR colors for( int n = 0; n <= 10; n++ ) { int c1 = 220 - ( 22 * n ); int c2 = 255 - ( 7 * n ); colorSNR[n] = Color.FromArgb(c1, c2, c2); } for( int n = 11; n <= 20; n++ ) { int c2 = (int)(190 * ( 2 - n/10d )); colorSNR[n] = Color.FromArgb(0, c2, c2); } Color[] colorSwg = new Color[21]; // Corona chart Swing colors for( int n = 0; n <= 10; n++ ) { int c1 = 180 - ( 18 * n ); int c2 = 255 - ( 8 * n ); int c3 = 210 - ( 15 * n ); colorSwg[n] = Color.FromArgb(c1, c2, c3); } for( int n = 11; n <= 20; n++ ) { int c2 = (int)(172 * ( 2 - n/10d )); int c3 = (int)(64 * ( 2 - n/10d )); colorSwg[n] = Color.FromArgb(0, c2, c3); } Color[] colorTV = new Color[21]; // Trend Vigor chart colors for( int n = 0; n <= 10; n++ ) { int c1 = 60 - ( 6 * n ); int c2 = 120 - ( 12 * n ); colorTV[n] = Color.FromArgb(c1, c2, 255); } for( int n = 11; n <= 20; n++ ) colorTV[n] = Color.FromArgb(0, 0, (int)(255 * ( 2 - n/10d ))); // Detrend data by High Pass Filtering with a 40 Period cutoff DataSeries HP = domCyc; double alpha = (1 - Math.Sin(twoPi/30)) / Math.Cos(twoPi/30); for(int bar = 1; bar < Bars.Count; bar++) HP[bar] = 0.5 * (1 + alpha)* Momentum.Series(ds, 1)[bar] + alpha * HP[bar-1]; DataSeries smoothHP = FIR.Series(HP, "1,2,3,3,2,1"); DataSeries hmlSer = Median.Series( High - Low, 5 ); double avg, signal, noise, snr; // Variables SNR double avg1 = 0d; double signal1 = 0d; double noise1 = 0d; const double delta2 = 0.1; // Variables Swing, TV double BP2_1 = 0d; double BP2_2 = 0d; double beta2, BP2, g2, alpha2, Q2, Lead60, HL, LL, widthSwg; ArrayList fifoList = new ArrayList(51); ArrayList fifoPsn = new ArrayList(21); double ratio = 0d; double ratio1 = 0d; double widthTV = 0d; // arrays to hold raster values from previous bar int[] raster2 = new int[51]; int[] raster2Swg = new int[51]; int[] raster2TV = new int[51]; for( int bar = 12; bar < Bars.Count; bar++ ) { double maxAmpl = 0d; double delta = -0.015 * bar + 0.5; delta = delta < 0.1 - 0.1 : delta; for( int n = 12; n < 61; n++ ) { double beta = Math.Cos(fourPi / n); double g = 1 / Math.Cos(2 * fourPi * delta / n); double a = g - Math.Sqrt(g * g - 1); ah[n].Q = Momentum.Series(smoothHP, 1)[bar] * n / fourPi; ah[n].I = smoothHP[bar]; ah[n].R = 0.5 * (1 - a) * (ah[n].I - ah[n].I3) + beta * (1 + a) * ah[n].R2 - a * ah[n].R3; ah[n].Im = 0.5 * (1 - a) * (ah[n].Q - ah[n].Q3) + beta * (1 + a) * ah[n].Im2 - a * ah[n].Im3; ah[n].A = ah[n].R * ah[n].R + ah[n].Im * ah[n].Im; maxAmpl = ah[n].A > maxAmpl - ah[n].A : maxAmpl; } double num = 0; double den = 0; for( int n = 12; n < 61; n++ ) { ah[n].I3 = ah[n].I2; ah[n].I2 = ah[n].I; ah[n].Q3 = ah[n].Q2; ah[n].Q2 = ah[n].Q; ah[n].R3 = ah[n].R2; ah[n].R2 = ah[n].R; ah[n].Im3 = ah[n].Im2; ah[n].Im2 = ah[n].Im; ah[n].dB2 = ah[n].dB; if( maxAmpl != 0 && ah[n].A / maxAmpl > 0 ) ah[n].dB = 10 * Math.Log10( (1 - 0.99 * ah[n].A / maxAmpl) / 0.01 ); ah[n].dB = 0.33 * ah[n].dB + 0.67 * ah[n].dB2; ah[n].dB = ah[n].dB > 20 - 20 : ah[n].dB; SetSeriesBarColor(bar, DB[n], color[(int)Math.Round(ah[n].dB)]); if( ah[n].dB <= 6 ) { num += n * (20 - ah[n].dB); den += (20 - ah[n].dB); } if( den != 0 ) domCycle = 0.5 * num / den; } domCycMdn[bar] = Median.Value(bar, domCyc, 5); domCycMdn[bar] = domCycle < 6 - 6: domCycle; // Calculate SNR this bar signal = 0d; noise = 0d; snr = 0d; avg = 0.1 * ds[bar] + 0.9 * avg1; if( avg != 0d || maxAmpl > 0 ) signal = 0.2 * Math.Sqrt(maxAmpl) + 0.9 * signal1; if( avg != 0d ) noise = 0.1 * hmlSer[bar] + 0.9 * noise1; if( signal != 0d || noise != 0d ) snr = 20 * Math.Log10(signal/noise) + 3.5; snr = snr < 1d - 0d : snr; snr = snr > 10d - 10d : snr; snr = snr * 0.1; snrSer[bar] = snr * 10 + 1; double Width = snr > 0.5 - 0d : -0.4 * snr + 0.2; // Calculate the Swing this bar beta2 = Math.Cos(twoPi / domCycMdn[bar]); g2 = 1 / Math.Cos(fourPi * delta2 / domCycMdn[bar]); alpha2 = g2 - Math.Sqrt(g2 * g2 - 1); BP2 = 0.5 * (1 - alpha2) * (ds[bar] - ds[bar-2]) + beta2 * (1 + alpha2) * BP2_1 - alpha2 * BP2_2; //Quadrature component is derivative of InPhase component divided by omega Q2 = (domCycMdn[bar] / twoPi) * (BP2 - BP2_1); Lead60 = 0.5 * BP2 + 0.866 * Q2; PhaseList(ref fifoList, 50, Lead60, out HL, out LL); double Psn = (Lead60 - LL) / (HL - LL); PhaseList(ref fifoPsn, 20, Psn, out HL, out LL); if( HL - LL > 0.85 ) widthSwg = 0.01; else widthSwg = 0.15 * (HL - LL); psnSer[bar] = 10 * Psn - 5d; // Calculate Trend Vigor this bar // (Filter Bandpass component - same as Swing above; substitute variable names) //Pythagorean theorem to establish cycle amplitude double Ampl2 = Math.Sqrt(BP2 * BP2 + Q2 * Q2); //Trend amplitude taken over the cycle period int cycPeriod = (int)(domCycMdn[bar] - 1); if( cycPeriod < 12 ) cycPeriod = 12; double Trend = ds[bar] - ds[cycPeriod]; if( Trend != 0 && Ampl2 != 0 ) ratio = 0.33 * Trend /Ampl2 + 0.67 * ratio1; if( ratio > 10 ) ratio = 10d; if( ratio < -10 ) ratio = -10d; double tv = 0.05 * (ratio + 10d); if( tv < 0.3 || tv > 0.7 ) widthTV = 0.01; if( tv >= 0.3 && tv < 0.5 ) widthTV = tv - 0.3; if( tv >= 0.5 && tv <= 0.7 ) widthTV = 0.7 - tv; tvSer[bar] = 20d * tv - 10d; /* Plot the rasters... */ int snr50 = (int)Math.Round(50 * snr); int psn50 = (int)Math.Round(50 * Psn); int tv50 = (int)Math.Round(50 * tv); for( int n = 1; n < 51; n++ ) { // 0.4 used below comes from 20/50 to normalize the color from 1 to 20 double raster = 20d; if( n < snr50 ) // bottom of corona raster = 0.5 * (Math.Pow((20 * snr - 0.4 * n) / Width, 0.8) + raster2[n]); else if( n > snr50 && (0.4 * n - 20 * snr) / Width > 1 ) // top of corona raster = 0.5 * (Math.Pow((-20 * snr + 0.4 * n) / Width, 0.8) + raster2[n]); else if( n == snr50 ) raster = 0.5 * raster2[n]; if ( raster > 20 ) raster = 20; else if ( raster < 0 ) raster = 0; if ( snr > 0.5 ) raster = 20; SetSeriesBarColor(bar, Raster[n], colorSNR[(int)(raster)]); raster2[n] = (int)raster; // Plot the Swing raster double rasterSwg = 20d; if( n < psn50 ) // bottom of corona rasterSwg = 0.5 * (Math.Pow((20 * Psn - 0.4 * n) / widthSwg, 0.95) + 0.5 * raster2Swg[n]); else if( n > psn50 && (0.4 * n - 20 * Psn) / widthSwg > 1 ) // top of corona rasterSwg = 0.5 * (Math.Pow((-20 * Psn + 0.4 * n) / widthSwg, 0.95) + 0.5 * raster2Swg[n]); else if( n == psn50 ) rasterSwg = 0.5 * raster2Swg[n]; if ( rasterSwg > 20 ) rasterSwg = 20; else if ( rasterSwg < 0 ) rasterSwg = 0; if ( HL - LL > 0.8 ) rasterSwg = 20; SetSeriesBarColor(bar, RasterSwg[n], colorSwg[(int)(rasterSwg)]); raster2Swg[n] = (int)rasterSwg; // Plot the Trend Vigor raster double rasterTV = 20d; if( n < tv50 ) rasterTV = 0.8 * (Math.Pow((20 * tv - 0.4 * n) / widthTV, 0.85) + 0.2 * raster2TV[n]); else if( n > tv50 ) // top of corona rasterTV = 0.8 * (Math.Pow((-20 * tv + 0.4 * n) / widthTV, 0.85) + 0.2 * raster2TV[n]); else if( n == tv50 ) rasterTV = 0.5 * raster2TV[n]; if( rasterTV < 0 ) rasterTV = 0; if( rasterTV > 20 || tv < 0.3 || tv > 0.7 ) rasterTV = 20; SetSeriesBarColor(bar, RasterTV[n], colorTV[(int)(rasterTV)]); raster2TV[n] = (int)rasterTV; } avg1 = avg; signal1 = signal; noise1 = noise; BP2_2 = BP2_1; BP2_1 = BP2; ratio1 = ratio; } HideVolume(); HidePaneLines(); PlotSeries(dbPane, domCycMdn, Color.Yellow, WealthLab.LineStyle.Solid, 2); DrawLabel(dbPane, "Dominant Cycle|", Color.Black); PlotSeries(snrPane, snrSer, Color.FromArgb(220, 255, 255), LineStyle.Solid, 2); DrawLabel(snrPane, "SNR|", Color.Black); PlotSeries(swgPane, psnSer, Color.FromArgb(180, 255, 210), LineStyle.Solid, 2); DrawLabel(swgPane, "Swing Position|", Color.Black); PlotSeries(tvPane, tvSer, Color.FromArgb(64, 128, 255), LineStyle.Solid, 2); DrawLabel(tvPane, "Trend Vigor|", Color.Black); } protected override void Execute() { // Declare the DataSeries to pass to the method DataSeries dc, snr, swing, tv; // Get the dominant cycle, SNR, Swing Position, and Trend Vigor for use in a strategy SuperIndicators(AveragePrice.Series(Bars), out dc, out snr, out swing, out tv); } } }-- Robert SucherGO BACK
www.wealth-lab.com
eSIGNAL: CORONA CHARTS
For this month's Traders' Tip, we've provided the following eSignal formulas
based on the formula code from John Ehlers's article in this issue, "Corona Charts." Figures 3 and 4 show sample implementations of the various corona charting indicators. To discuss this study or download a complete copy of the eSignal formula code, please visit the EFS Library Discussion Board forum under the Forums link at www.esignalcentral.com or visit our EFS KnowledgeBase at www.esignalcentral.com/support/kb/efs/. The eSignal formula scripts (EFS) are also available for copying and pasting from the Stocks & Commodities website at Traders.com.
- CoronaChartCyclePeriod.efs,
- CoronaChartSignalToNoiseRatio.efs,
- CoronaChartSwingPosition.efs, and
- CoronaChartTrendVigor.efs
FIGURE 3: eSIGNAL, CORONA CHART. This sample eSignal corona chart shows the cycle period and signal-to-noise-ratio indicators.
FIGURE 4: eSIGNAL, CORONA CHART. This sample eSignal corona chart shows the swing position and trend vigor indicators.eSignal code Corona Chart Trend Vigor EFS code: /********************************* Provided By: eSignal (Copyright c eSignal), a division of Interactive Data Corporation. 2008. All rights reserved. This sample eSignal Formula Script (EFS) is for educational purposes only and may be modified and saved under a new file name. eSignal is not responsible for the functionality once modified. eSignal reserves the right to modify and overwrite this EFS file with each new release. Description: Corona Chart Trend Vigor Version: 1.0 9/10/2008 Notes: Once the dominant cycle period is known, the instantaneous trend is just the momentum across the full cycle period. This measurement is invariant with the position within the cycle. The trend slope is the same whether measured from cycle peak to cycle peak or cycle valley to cycle valley. The trend slope is normalized to the amplitude of the dominant cycle. A value of +2 means the trend slope is twice the dominant cycle amplitude, and therefore cautions you not to trade against the upslope. Similarly, a value of -2 means the trend slope is down and therefore cautions you not to buy against the downslope. The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com. Formula Parameters: Default: View Line Trend Vigor True **********************************/ var fpArray = new Array(); var bInit = false; var bVersion = null; function preMain() { setPriceStudy(false); setShowCursorLabel(false); setShowTitleParameters( false ); setStudyTitle("Corona Chart Trend Vigor"); var x=0; fpArray[x] = new FunctionParameter("ViewLine", FunctionParameter.BOOLEAN); with(fpArray[x++]){ setName("View Line Trend Vigor"); setDefault(true); } } var nLineR = 64; var nLineG = 128; var nLineB = 255; var nFuzzR = 0; var nFuzzG = 0; var nFuzzB = 255; var xPrice = null; var nRef_Global = 0; var ndelta = 0.1; var ngamma = 0; var nalpha = 0; var nbeta = 0; var nN = 0; var nPeriod = 0; var nMaxAmpl = 0; var nNum = 0; var nDenom = 0; var nDC = 0; var nDomCyc = 0; var nColor1 = 0; var nColor2 = 0; var nColor3 = 0; var nalpha1 = 0; var xHP = null; var nSmoothHP = 0; var nSmoothHP1 = 0; var ndelta1 = 0.1; var ngamma1 = 0; var nalpha2 = 0; var nbeta1 = 0; var nIP2 = 0; var nIP1 = 0; var nIP = 0; var nQ1 = 0; var nAmpl2 = 0; var nTrend = 0; var nRatio = 0; var nRatio1 = 0; var nTV = 0; var nWidth = 0; var xResultArray = new Array(52); var aI = new Array(60); var aOldI = new Array(60); var aOlderI = new Array(60); var aQ = new Array(60); var aOldQ = new Array(60); var aOlderQ = new Array(60); var aReal = new Array(60); var aOldReal = new Array(60); var aOlderReal = new Array(60); var aImag = new Array(60); var aOldImag = new Array(60); var aOlderImag = new Array(60); var aAmpl = new Array(60); var aOldAmpl = new Array(60); var aDB = new Array(60); var aOldDB = new Array(60); var aDC = new Array(60); var aRaster = new Array(50); var aOldRaster = new Array(50); function main(ViewLine) { var nResCounter = 0; var nState = getBarState(); var pi = 3.1415926; if (bVersion == null) bVersion = verify(); if (bVersion == false) return; if (nState == BARSTATE_ALLBARS) { resetGlobalVars(); } nalpha1 = (1 - (Math.sin(pi * (360 / 30) / 180)) / (Math.cos(pi * (360 / 30) / 180))); if (nState == BARSTATE_NEWBAR) { nSmoothHP1 = nSmoothHP; } if ( bInit == false ) { bShowDC = ViewLine; xPrice = hl2(); xHP = efsInternal("Calc_HP";, xPrice, nalpha1); bInit = true; drawTextPixel( 10, 10,"Corona Chart Trend Vigor", Color.black, null, Text.RELATIVETOLEFT | Text.RELATIVETOTOP, "Name" ,10, -10 ); } if (getCurrentBarCount() < 7) return; if (nState == BARSTATE_NEWBAR) { aDC.pop(); aDC.unshift(nDC); nRatio1 = nRatio; nIP2 = nIP1; nIP1 = nIP; for (nN = 12; nN <= 60; nN++) { aOlderI[nN] = aOldI[nN]; aOldI[nN] = aI[nN]; aOlderQ[nN] = aOldQ[nN]; aOldQ[nN] = aQ[nN]; aOlderReal[nN] = aOldReal[nN]; aOldReal[nN] = aReal[nN]; aOlderImag[nN] = aOldImag[nN]; aOldImag[nN] = aImag[nN]; aOldAmpl[nN] = aAmpl[nN]; aOldDB[nN] = aDB[nN]; } for (nN = 1; nN < 51; nN++) { aOldRaster[nN] = aRaster[nN]; } } nSmoothHP = 0; if (xPrice.getValue(-1) != null) nSmoothHP = 0; else nSmoothHP = xPrice.getValue(0) - xPrice.getValue(-1); if (xHP.getValue(-5) != null) { nSmoothHP = (xHP.getValue(0) + 2 * xHP.getValue(-1) + 3 * xHP.getValue(-2) + 3 * xHP.getValue(-3) + 2 * xHP.getValue(-4) + xHP.getValue(-5)) / 12; } ndelta = (-0.015) * getCurrentBarCount() + 0.5; if (ndelta < 0.1) ndelta = 0.1; if (getCurrentBarCount() > 12) { for (nN = 12; nN <= 60; nN++) { nbeta = Math.cos(pi * (720 / nN) / 180); ngamma = 1 / Math.cos(pi * (1440 * ndelta / nN) / 180); nalpha = ngamma - Math.sqrt(ngamma * ngamma - 1); aQ[nN] = (0.5 * nN / 6.28318) * (nSmoothHP - nSmoothHP1); aI[nN] = nSmoothHP; aReal[nN] = 0.5 * (1 - nalpha) * (aI[nN] - aOlderI[nN]) + nbeta * (1 + nalpha) * aOldReal[nN] - nalpha * aOlderReal[nN]; aImag[nN] = 0.5 * (1 - nalpha) * (aQ[nN] - aOlderQ[nN]) + nbeta * (1 + nalpha) * aOldImag[nN] - nalpha * aOlderImag[nN]; aAmpl[nN] = (aReal[nN] * aReal[nN] + aImag[nN] * aImag[nN]); } } nMaxAmpl = aAmpl[12]; for (nN = 12; nN <= 60; nN++) { if (aAmpl[nN] > nMaxAmpl) nMaxAmpl = aAmpl[nN]; } for (nN = 12; nN <= 60; nN++) { if (nMaxAmpl != 0 && (aAmpl[nN] / nMaxAmpl) > 0) aDB[nN] = (-10) * Math.log(0.01 / (1 - 0.99 * aAmpl[nN] / nMaxAmpl)) / Math.log(10); aDB[nN] = 0.33 * aDB[nN] + 0.67 * aOldDB[nN]; if (aDB[nN] > 20) aDB[nN] = 20; } nNum = 0; nDenom = 0; for (nN = 12; nN <= 60; nN++) { if (aDB[nN] <= 6) { nNum = nNum + nN * (20 - aDB[nN]); nDenom = nDenom + (20 - aDB[nN]); } if (nDenom != 0) { nDC = 0.5 * nNum / nDenom; aDC[0] = nDC; } } nDomCyc = Median(aDC, 5); if (nDomCyc < 6) nDomCyc = 6; nbeta1 = Math.cos(pi * (360 / nDomCyc) / 180); ngamma1 = 1 / Math.cos(pi * (720 * ndelta1 / nDomCyc) / 180); nalpha2 = ngamma1 - Math.sqrt(ngamma1 * ngamma1 - 1); nIP = 0.5 * (1 - nalpha2) * (xPrice.getValue(0) - xPrice.getValue(-2)) + nbeta1 * (1 + nalpha2) * nIP1 - nalpha2 * nIP2; nQ1 = (nDomCyc / 6.28318) * (nIP - nIP1); nAmpl2 = Math.sqrt(nIP * nIP + nQ1 * nQ1); nTrend = xPrice.getValue(0) - xPrice.getValue(-nDomCyc + 1); if (nTrend != 0 && nAmpl2 != 0) nRatio = 0.33 * nTrend / nAmpl2 + 0.67 * nRatio1; if (nRatio > 10) nRatio = 10; if (nRatio < (-10)) nRatio = (-10); nTV = 0.05 * (nRatio + 10); if (nTV < 0.3 || nTV > 0.7) nWidth = 0.01; if (nTV >= 0.3 && nTV < 0.5) nWidth = nTV - 0.3; if (nTV > 0.5 && nTV <= 0.7) nWidth = -nTV + 0.7; for (nN = 1; nN < 51; nN++) { aRaster[nN] = 20; if (nN < Math.round(50 * nTV)) aRaster[nN] = 0.8 * (Math.pow((20 * nTV - 0.4 * nN) / nWidth, 0.85) + 0.2 * aOldRaster[nN]); if (nN > Math.round(50 * nTV)) aRaster[nN] = 0.8 * (Math.pow((-20 * nTV + 0.4 * nN) / nWidth, 0.85) + 0.2 * aOldRaster[nN]); if (nN == Math.round(50 * nTV)) aRaster[nN] = 0.5 * aOldRaster[nN]; if (aRaster[nN] < 0) aRaster[nN] = 0; if (aRaster[nN] > 20 || nTV < 0.3 || nTV > 0.7) aRaster[nN] = 20; } for (nN = 1; nN < 51; nN++) { if (aRaster[nN] <= 10) { nColor1 = Math.round(nLineR + aRaster[nN] * (nFuzzR - nLineR) / 10); nColor2 = Math.round(nLineG + aRaster[nN] * (nFuzzG - nLineG) / 10); nColor3 = Math.round(nLineB + aRaster[nN] * (nFuzzB - nLineB) / 10); } if (aRaster[nN] > 10) { nColor1 = Math.round(nFuzzR * (2 - aRaster[nN] / 10)); nColor2 = Math.round(nFuzzG * (2 - aRaster[nN] / 10)); nColor3 = Math.round(nFuzzB * (2 - aRaster[nN] / 10)); } xResultArray[nResCounter++] = 0.4 * nN - 10; setDefaultBarFgColor(Color.RGB(nColor1, nColor2, nColor3), nResCounter-1); setDefaultBarThickness(5, nResCounter - 1); } if (bShowDC == true) { xResultArray[nResCounter++] = (20 * nTV - 10); setBarFgColor(Color.RGB(nLineR, nLineG, nLineB), nResCounter-1); setBarThickness(3, nResCounter-1); } return xResultArray; } function resetGlobalVars(){ nRef_Global = 0; ndelta = 0.1; ngamma = 0; nalpha = 0; nbeta = 0; nN = 0; nPeriod = 0; nMaxAmpl = 0; nNum = 0; nDenom = 0; nDC = 0; nDomCyc = 0; nColor1 = 0; nColor2 = 0; nColor3 = 0; nalpha1 = 0; nSmoothHP = 0; nSmoothHP1 = 0; ndelta1 = 0.1; ngamma1 = 0; nalpha2 = 0; nbeta1 = 0; nIP2 = 0; nIP1 = 0; nIP = 0; nQ1 = 0; nAmpl2 = 0; nTrend = 0; nRatio = 0; nRatio1 = 0; nTV = 0; nWidth = 0; for (var i = 0; i < 61; i++) { if (i <= 52) xResultArray[i] = null; aI[i] = 0; aOldI[i] = 0; aOlderI[i] = 0; aQ[i] = 0; aOldQ[i] = 0; aOlderQ[i] = 0; aReal[i] = 0; aOldReal[i] = 0; aOlderReal[i] = 0; aImag[i] = 0; aOldImag[i] = 0; aOlderImag[i] = 0; aAmpl[i] = 0; aOldAmpl[i] = 0; aDB[i] = 0; aOldDB[i] = 0; aDC[i] = 0; } for (var i = 1; i < 51; i++) { aRaster[i] = 0; aOldRaster[i] = 0; } } // calcHP globals var nPrevHP = null; var nCurrHP = null; function Calc_HP(x, nAlpha1) { 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 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=https://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; }Corona Chart Swing Position EFS code:
/********************************* Provided By: eSignal (Copyright c eSignal), a division of Interactive Data Corporation. 2008. All rights reserved. This sample eSignal Formula Script (EFS) is for educational purposes only and may be modified and saved under a new file name. eSignal is not responsible for the functionality once modified. eSignal reserves the right to modify and overwrite this EFS file with each new release. Description: Corona Chart Swing Position Version: 1.0 9/10/2008 Notes: The swing position indicator shows the phasing of the data within the dominant cycle. A value of -5 means the cycle is at its valley. A value of +5 means the cycle is at its peak. In a pure cycle the Swing Position will trace out the shape of a sine wave. The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com. Formula Parameters: Default: View Line True **********************************/ var fpArray = new Array(); var bInit = false; var bVersion = null; function preMain() { setPriceStudy(false); setShowCursorLabel(false); setShowTitleParameters( false ); setStudyTitle("Corona Chart Swing Position"); setDefaultBarThickness(3, 50); var x=0; fpArray[x] = new FunctionParameter("ViewLine", FunctionParameter.BOOLEAN); with(fpArray[x++]){ setName("View Line"); setDefault(true); } } var nLineR = 180; var nLineG = 255; var nLineB = 210; var nFuzzR = 0; var nFuzzG = 172; var nFuzzB = 64; var xPrice = null; var nRef_Global = 0; var ndelta = 0.1; var ngamma = 0; var nalpha = 0; var nbeta = 0; var nN = 0; var nPeriod = 0; var nMaxAmpl = 0; var nNum = 0; var nDenom = 0; var nDC = 0; var nDomCyc = 0; var nColor1 = 0; var nColor2 = 0; var nColor3 = 0; var nalpha1 = 0; var xHP = null; var nSmoothHP = 0; var nSmoothHP1 = 0; var ngamma2 = 0; var nalpha2 = 0; var nbeta2 = 0; var ndelta2 = 0.1; var nBP2 = 0; var nBP2_1 = 0; var nBP2_2 = 0; var nQ2 = 0; var nHL = 0; var nLL = 0; var ncount = 0; var nWidth = 0; var nCalc_HP_Ref = 0; var xResultArray = new Array(51); var aI = new Array(61); var aOldI = new Array(61); var aOlderI = new Array(61); var aQ = new Array(61); var aOldQ = new Array(61); var aOlderQ = new Array(61); var aReal = new Array(61); var aOldReal = new Array(61); var aOlderReal = new Array(61); var aImag = new Array(61); var aOldImag = new Array(61); var aOlderImag = new Array(61); var aAmpl = new Array(61); var aOldAmpl = new Array(61); var aDB = new Array(61); var aOldDB = new Array(61); var aDC = new Array(61); var aPsn = new Array(61); var aRaster = new Array(51); var aOldRaster = new Array(51); var aLead60 = new Array(51); function main(ViewLine) { var nResCounter = 0; var nState = getBarState(); var pi = 3.1415926; var nCounter = 0; if (bVersion == null) bVersion = verify(); if (bVersion == false) return; if (nState == BARSTATE_ALLBARS) { resetVars(); } nalpha1 = (1 - (Math.sin(pi * (360 / 30) / 180)) / (Math.cos(pi * (360 / 30) / 180))); if ( bInit == false ) { bShowDC = ViewLine; xPrice = hl2(); xHP = efsInternal("Calc_HP", xPrice, nalpha1); bInit = true; drawTextPixel( 10, 10,"J Corona Chart Swing Position", Color.black, null, Text.RELATIVETOLEFT | Text.RELATIVETOTOP, "Name" ,10, -10 ); } if (getCurrentBarCount() < 5) return; if (nState == BARSTATE_NEWBAR) { nSmoothHP1 = nSmoothHP; aDC.pop(); aDC.unshift(nDC); aLead60.pop(); aLead60.unshift(0.5 * nBP2 + 0.866 * nQ2); aPsn.pop(); aPsn.unshift((aLead60[0] - nLL) / (nHL - nLL)); nBP2_2 = nBP2_1; nBP2_1 = nBP2; for (nN = 12; nN <= 60; nN++) { aOlderI[nN] = aOldI[nN]; aOldI[nN] = aI[nN]; aOlderQ[nN] = aOldQ[nN]; aOldQ[nN] = aQ[nN]; aOlderReal[nN] = aOldReal[nN]; aOldReal[nN] = aReal[nN]; aOlderImag[nN] = aOldImag[nN]; aOldImag[nN] = aImag[nN]; aOldAmpl[nN] = aAmpl[nN]; aOldDB[nN] = aDB[nN]; } } nSmoothHP = 0 if (xPrice.getValue(-1) != null) nSmoothHP = xPrice.getValue(0) - xPrice.getValue(-1); if (xHP.getValue(-5) != null) { nSmoothHP = (xHP.getValue(0) + 2 * xHP.getValue(-1) + 3 * xHP.getValue(-2) + 3 * xHP.getValue(-3) + 2 * xHP.getValue(-4) + xHP.getValue(-5)) / 12; } ndelta = (-0.015) * getCurrentBarCount() + 0.5; if (ndelta < 0.1) ndelta = 0.1; if (getCurrentBarCount() > 12) { for (nN = 12; nN <= 60; nN++) { nbeta = Math.cos(pi * (720 / nN) / 180); ngamma = 1 / Math.cos(pi * (1440 * ndelta / nN) / 180); nalpha = ngamma - Math.sqrt(ngamma * ngamma - 1); aQ[nN] = (0.5 * nN / 6.28318) * (nSmoothHP - nSmoothHP1); aI[nN] = nSmoothHP; aReal[nN] = 0.5 * (1 - nalpha) * (aI[nN] - aOlderI[nN]) + nbeta * (1 + nalpha) * aOldReal[nN] - nalpha * aOlderReal[nN]; aImag[nN] = 0.5 * (1 - nalpha) * (aQ[nN] - aOlderQ[nN]) + nbeta * (1 + nalpha) * aOldImag[nN] - nalpha * aOlderImag[nN]; aAmpl[nN] = (aReal[nN] * aReal[nN] + aImag[nN] * aImag[nN]); } } nMaxAmpl = aAmpl[12]; for (nN = 12; nN <= 60; nN++) { if (aAmpl[nN] > nMaxAmpl) nMaxAmpl = aAmpl[nN]; } for (nN = 12; nN <= 60; nN++) { if (nMaxAmpl != 0 && (aAmpl[nN] / nMaxAmpl) > 0) aDB[nN] = (-10) * Math.log(0.01 / (1 - 0.99 * aAmpl[nN] / nMaxAmpl)) / Math.log(10); aDB[nN] = 0.33 * aDB[nN] + 0.67 * aOldDB[nN]; if (aDB[nN] > 20) aDB[nN] = 20; } nNum = 0; nDenom = 0; for (nN = 12; nN <= 60; nN++) { if (aDB[nN] <= 6) { nNum = nNum + nN * (20 - aDB[nN]); nDenom = nDenom + (20 - aDB[nN]); } if (nDenom != 0) { nDC = 0.5 * nNum / nDenom; aDC[0] = nDC; } } nDomCyc = Median(aDC, 5); if (nDomCyc < 6) nDomCyc = 6; nbeta2 = Math.cos(pi * (360 / nDomCyc) / 180); ngamma2 = 1 / Math.cos(pi * (720 * ndelta2 / nDomCyc) / 180); nalpha2 = ngamma2 - Math.sqrt(ngamma2 * ngamma2 - 1); nBP2 = 0.5 * (1 - nalpha2) * (xPrice.getValue(0) - xPrice.getValue(-1)) + nbeta2 * (1 + nalpha2) * nBP2_1 - nalpha2 * nBP2_2; nQ2 = (nDomCyc / 6.28318)*(nBP2 - nBP2_1); aLead60[0] = 0.5 * nBP2 + 0.866 * nQ2; nHL = aLead60[0]; nLL = aLead60[0]; for (ncount = 0; ncount < 51; ncount++) { if (aLead60[ncount] > nHL) nHL =aLead60[ncount]; if (aLead60[ncount] < nLL) nLL = aLead60[ncount]; } aPsn[0] = (aLead60[0] - nLL) / (nHL - nLL); nHL = aPsn[0]; nLL = aPsn[0]; for (ncount = 0; ncount < 21; ncount++) { if (aPsn[ncount] > nHL) nHL = aPsn[ncount]; if (aPsn[ncount] < nLL) nLL = aPsn[ncount]; } if (nHL - nLL > 0.85) { nWidth = 0.01 } else { nWidth = 0.15 * (nHL - nLL);} for (nN = 1; nN < 51; nN++) { aRaster[nN] = 20; if (nN < Math.round(50 * aPsn[0])) aRaster[nN] = 0.5 * (Math.pow(((20 * aPsn[0] - 0.4 * nN) / nWidth), 0.95) + 0.5 * aOldRaster[nN]); if (nN > Math.round(50 * aPsn[0])) aRaster[nN] = 0.5 * (Math.pow((((-20) * aPsn[0] + 0.4 * nN) / nWidth), 0.95) + 0.5 * aOldRaster[nN]); if (nN == Math.round(50 * aPsn[0])) aRaster[nN] = 0.5 * aOldRaster[nN]; if (aRaster[nN] < 0) aRaster[nN] = 0; if (aRaster[nN] > 20) aRaster[nN] = 20; if (nHL - nLL > 0.8) aRaster[nN] = 20; aOldRaster[nN] = aRaster[nN]; } for (nN = 1; nN < 51; nN++) { if (aRaster[nN] <= 10) { nColor1 = Math.round(nLineR + aRaster[nN] * (nFuzzR - nLineR) / 10); nColor2 = Math.round(nLineG + aRaster[nN] * (nFuzzG - nLineG) / 10); nColor3 = Math.round(nLineB + aRaster[nN] * (nFuzzB - nLineB) / 10); } if (aRaster[nN] > 10) { nColor1 = Math.round(nFuzzR * (2 - aRaster[nN] / 10)); nColor2 = Math.round(nFuzzG * (2 - aRaster[nN] / 10)); nColor3 = Math.round(nFuzzB * (2 - aRaster[nN] / 10)); } xResultArray[nResCounter++] = 0.2 * nN - 5; setBarFgColor(Color.RGB(nColor1, nColor2, nColor3), nResCounter-1); setPlotType(PLOTTYPE_LINE, nResCounter-1); setBarThickness(5, nResCounter-1); } if (bShowDC == true) { xResultArray[nResCounter++] = (10 * aPsn[0] - 5); setBarFgColor(Color.RGB(nLineR, nLineG, nLineB), nResCounter-1); } return xResultArray; } function resetVars() { nRef_Global = 0; ndelta = 0.1; ngamma = 0; nalpha = 0; nbeta = 0; nN = 0; nPeriod = 0; nMaxAmpl = 0; nNum = 0; nDenom = 0; nDC = 0; nDomCyc = 0; nColor1 = 0; nColor2 = 0; nColor3 = 0; nalpha1 = 0; nSmoothHP = 0; nSmoothHP1 = 0; ngamma2 = 0; nalpha2 = 0; nbeta2 = 0; ndelta2 = 0.1; nBP2 = 0; nBP2_1 = 0; nBP2_2 = 0; nQ2 = 0; nHL = 0; nLL = 0; ncount = 0; nWidth = 0; nCalc_HP_Ref = 0; for (var i = 0; i < 61; i++) { if (i < 51) xResultArray[i] = null; aI[i] = 0; aOldI[i] = 0; aOlderI[i] = 0; aQ[i] = 0; aOldQ[i] = 0; aOlderQ[i] = 0; aReal[i] = 0; aOldReal[i] = 0; aOlderReal[i] = 0; aImag[i] = 0; aOldImag[i] = 0; aOlderImag[i] = 0; aAmpl[i] = 0; aOldAmpl[i] = 0; aDB[i] = 0; aOldDB[i] = 0; aDC[i] = 0; aPsn[i] = 0; } for (var i = 0; i < 51; i++) { aRaster[i] = 0; aOldRaster[i] = 0; aLead60[i] = 0; } return; } // calcHP globals var nPrevHP = null; var nCurrHP = null; function Calc_HP(x, nAlpha1) { 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 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=https://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; }Corona Chart Signal To Noise EFS code:
/********************************* Provided By: eSignal (Copyright © eSignal), a division of Interactive Data Corporation. 2008. All rights reserved. This sample eSignal Formula Script (EFS) is for educational purposes only and may be modified and saved under a new file name. eSignal is not responsible for the functionality once modified. eSignal reserves the right to modify and overwrite this EFS file with each new release. Description: Corona Chart Signal To Noise Ratio Version: 1.0 9/10/2008 Notes: The amplitude of the dominant cycle is normalized to the amplitude of the noise. Noise is defined as the average daily trading range. The Signal to Noise Ratio is measured in decibels (dB). Unless the cycle amplitude is at least 3 dB greater than the noise, the use of cycle-based entries and oscillators should be avoided because the uncertainty of getting a good entry and exit point during day can negate any potential profit realized from the cyclic swing. A Signal to Noise ratio in excess of 6 dB signals a strong cyclic component relative to the noise. The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com. Formula Parameters: Default: View Line Signal To Noise Ratio True **********************************/ var fpArray = new Array(); var bInit = false; var bVersion = null; function preMain() { setPriceStudy(false); setShowCursorLabel(false); setShowTitleParameters( false ); setStudyTitle("Corona Chart Signal To Noise Ratio"); var x=0; fpArray[x] = new FunctionParameter("ViewLine", FunctionParameter.BOOLEAN); with(fpArray[x++]){ setName("View Line Signal To Noise Ratio"); setDefault(true); } } var xResultArray = new Array(50); var nLineR = 220; var nLineG = 255; var nLineB = 255; var nFuzzR = 0; var nFuzzG = 190; var nFuzzB = 190; var xPrice = null; var nRef_Global = 0; var ndelta = 0.1; var ngamma = 0; var nalpha = 0; var nbeta = 0; var nN = 0; var nPeriod = 0; var nMaxAmpl = 0; var nNum = 0; var nDenom = 0; var nDC = 0; var nDomCyc = 0; var nColor1 = 0; var nColor2 = 0; var nColor3 = 0; var nalpha1 = 0; var xHP = null; var nSmoothHP = 0; var nSmoothHP1 = 0; var nAvg1 = 0; var nAvg = 0; var nSignal = 0; var nSignal1 = 0; var nNoise = 0; var nNoise1 = 0; var nSNR = 0; var nWidth = 0; var aI = new Array(60); var aOldI = new Array(60); var aOlderI = new Array(60); var aQ = new Array(60); var aOldQ = new Array(60); var aOlderQ = new Array(60); var aReal = new Array(60); var aOldReal = new Array(60); var aOlderReal = new Array(60); var aImag = new Array(60); var aOldImag = new Array(60); var aOlderImag = new Array(60); var aAmpl = new Array(60); var aOldAmpl = new Array(60); var aDB = new Array(60); var aOldDB = new Array(60); var aDC = new Array(60); var aRaster = new Array(50); var aOldRaster = new Array(50); function main(ViewLine) { var nResCounter = 0; var nState = getBarState(); var pi = 3.1415926; var nCounter = 0; if (bVersion == null) bVersion = verify(); if (bVersion == false) return; if (nState == BARSTATE_ALLBARS) { resetVars(); } nalpha1 = (1 - (Math.sin(pi * (360 / 30) / 180)) / (Math.cos(pi * (360 / 30) / 180))); if (nState == BARSTATE_NEWBAR) { nSmoothHP1 = nSmoothHP; nAvg1 = nAvg; nSignal1 = nSignal; nNoise1 = nNoise; } if ( bInit == false ) { bShowDC = ViewLine; xPrice = hl2(); xHP = efsInternal("Calc_HP", xPrice, nalpha1); bInit = true; drawTextPixel( 10, 10,"Corona Chart Signal To Noise Ratio", Color.black, null, Text.RELATIVETOLEFT | Text.RELATIVETOTOP, "Name" ,10, -10 ); } if (getCurrentBarCount() < 10) return; if (nState == BARSTATE_NEWBAR) { aDC.pop(); aDC.unshift(nDC); aDB.pop(); aDB.unshift(); for (nN = 12; nN <= 60; nN++) { aOlderI[nN] = aOldI[nN]; aOldI[nN] = aI[nN]; aOlderQ[nN] = aOldQ[nN]; aOldQ[nN] = aQ[nN]; aOlderReal[nN] = aOldReal[nN]; aOldReal[nN] = aReal[nN]; aOlderImag[nN] = aOldImag[nN]; aOldImag[nN] = aImag[nN]; aOldAmpl[nN] = aAmpl[nN]; aOldDB[nN] = aDB[nN]; } for (nN = 1; nN < 51; nN++) { aOldRaster[nN] = aRaster[nN]; } } nSmoothHP = 0; if (xPrice.getValue(-1) != null) nSmoothHP = 0; else nSmoothHP = xPrice.getValue(0) - xPrice.getValue(-1); if (xHP.getValue(-5) != null) { nSmoothHP = (xHP.getValue(0) + 2 * xHP.getValue(-1) + 3 * xHP.getValue(-2) + 3 * xHP.getValue(-3) + 2 * xHP.getValue(-4) + xHP.getValue(-5)) / 12; } ndelta = (-0.015) * getCurrentBarCount() + 0.5; if (ndelta < 0.1) ndelta = 0.1; if (getCurrentBarCount() > 12) { for (nN = 12; nN <= 60; nN++) { nbeta = Math.cos(pi * (720 / nN) / 180); ngamma = 1 / Math.cos(pi * (1440 * ndelta / nN) / 180); nalpha = ngamma - Math.sqrt(ngamma * ngamma - 1); aQ[nN] = (0.5 * nN / 6.28318) * (nSmoothHP - nSmoothHP1); aI[nN] = nSmoothHP; aReal[nN] = 0.5 * (1 - nalpha) * (aI[nN] - aOlderI[nN]) + nbeta * (1 + nalpha) * aOldReal[nN] - nalpha * aOlderReal[nN]; aImag[nN] = 0.5 * (1 - nalpha) * (aQ[nN] - aOlderQ[nN]) + nbeta * (1 + nalpha) * aOldImag[nN] - nalpha * aOlderImag[nN]; aAmpl[nN] = (aReal[nN] * aReal[nN] + aImag[nN] * aImag[nN]); } } nMaxAmpl = aAmpl[12]; for (nN = 12; nN <= 60; nN++) { if (aAmpl[nN] > nMaxAmpl) nMaxAmpl = aAmpl[nN]; //aOldDB[nN] = aDB[nN]; } for (nN = 12; nN <= 60; nN++) { if (nMaxAmpl != 0 && (aAmpl[nN] / nMaxAmpl) > 0) aDB[nN] = (-10) * Math.log(0.01 / (1 - 0.99 * aAmpl[nN] / nMaxAmpl)) / Math.log(10); aDB[nN] = 0.33 * aDB[nN] + 0.67 * aOldDB[nN]; if (aDB[nN] > 20) aDB[nN] = 20; } nNum = 0; nDenom = 0; for (nN = 12; nN <= 60; nN++) { if (aDB[nN] <= 6) { nNum = nNum + nN * (20 - aDB[nN]); nDenom = nDenom + (20 - aDB[nN]); } if (nDenom != 0) { nDC = 0.5 * nNum / nDenom; aDC[0] = nDC; } } nDomCyc = Median(aDC, 5); if (nDomCyc < 6) nDomCyc = 6; nAvg = 0.1 * xPrice.getValue(0) + 0.9 * nAvg1; if (nAvg != 0 && nMaxAmpl > 0) nSignal = 0.2 * Math.sqrt(nMaxAmpl) + 0.9 * nSignal1; if (nAvg != 0 && getCurrentBarCount() > 5) nNoise = 0.1 * Median2(5) + 0.9 * nNoise1; if (nSignal != 0 && nNoise != 0) nSNR = 20 * Math.log(nSignal / nNoise) / Math.log(10) + 3.5; if (nSNR < 1) nSNR = 0; if (nSNR > 11) nSNR = 10; nSNR = 0.1 * nSNR; nWidth = (-0.4) * nSNR + 0.2; if (nSNR > 0.5) nWidth = 0; for (nN = 1; nN < 51; nN++) { aRaster[nN] = 20; if (nN < Math.round(50 * nSNR)) aRaster[nN] = 0.5 * (Math.pow((20 * nSNR - 0.4 * nN) / nWidth, 0.8) + aOldRaster[nN]); if (nN > Math.round(50 * nSNR) && (0.4 * nN - 20 * nSNR) / nWidth > 1) aRaster[nN] = 0.5 * (Math.pow(((-20) * nSNR + 0.4 * nN)/ nWidth, 0.8) + aOldRaster[nN]) ; if (nN == Math.round(50 * nSNR)) aRaster[nN] = 0 + 0.5 * aOldRaster[nN]; if (aRaster[nN] < 0) aRaster[nN] = 0; if (aRaster[nN] > 20) aRaster[nN] = 20; if (nSNR > 0.5) aRaster[nN] = 20; } for (nN = 1; nN < 51; nN++) { if (aRaster[nN] <= 10) { nColor1 = Math.round(nLineR + aRaster[nN] * (nFuzzR - nLineR) / 10); nColor2 = Math.round(nLineG + aRaster[nN] * (nFuzzG - nLineG) / 10); nColor3 = Math.round(nLineB + aRaster[nN] * (nFuzzB - nLineB) / 10); } if (aRaster[nN] > 10) { nColor1 = Math.round(nFuzzR * (2 - aRaster[nN] / 10)); nColor2 = Math.round(nFuzzG * (2 - aRaster[nN] / 10)); nColor3 = Math.round(nFuzzB * (2 - aRaster[nN] / 10)); } xResultArray[nResCounter++] = 0.2 * nN + 1; setBarFgColor(Color.RGB(nColor1, nColor2, nColor3), nResCounter-1); setPlotType(PLOTTYPE_LINE, nResCounter-1); setBarThickness(5, nResCounter-1); } if (bShowDC == true) { xResultArray[nResCounter++] = 10 * nSNR + 1; setBarFgColor(Color.RGB(nLineR, nLineG, nLineB), nResCounter-1); setBarThickness(3, nResCounter-1); } return xResultArray; } function resetVars(){ nRef_Global = 0; ndelta = 0.1; ngamma = 0; nalpha = 0; nbeta = 0; nN = 0; nPeriod = 0; nMaxAmpl = 0; nNum = 0; nDenom = 0; nDC = 0; nDomCyc = 0; nColor1 = 0; nColor2 = 0; nColor3 = 0; nalpha1 = 0; nSmoothHP = 0; nSmoothHP1 = 0; nAvg1 = 0; nAvg = 0; nSignal = 0; nSignal1 = 0; nNoise = 0; nNoise1 = 0; nSNR = 0; nWidth = 0; for (var i = 0; i < 61; i++) { if (i <= 50) xResultArray[i] = null; aI[i] = 0; aOldI[i] = 0; aOlderI[i] = 0; aQ[i] = 0; aOldQ[i] = 0; aOlderQ[i] = 0; aReal[i] = 0; aOldReal[i] = 0; aOlderReal[i] = 0; aImag[i] = 0; aOldImag[i] = 0; aOlderImag[i] = 0; aAmpl[i] = 0; aOldAmpl[i] = 0; aDB[i] = 0; aOldDB[i] = 0; aDC[i] = 0; } for (var i = 0; i < 51; i++) { aRaster[i] = 0; aOldRaster[i] = 0; } return; } // calcHP globals var nPrevHP = null; var nCurrHP = null; function Calc_HP(x, nAlpha1) { 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 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 Median2(Length) { var aArray = new Array(Length); var nMedian = null; for (var i = 0; i < Length; i++) { aArray[i] = high(-i) - low(-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=https://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; } Corona Chart Cycle Period EFS code: /********************************* Provided By: eSignal (Copyright c eSignal), a division of Interactive Data Corporation. 2008. All rights reserved. This sample eSignal Formula Script (EFS) is for educational purposes only and may be modified and saved under a new file name. eSignal is not responsible for the functionality once modified. eSignal reserves the right to modify and overwrite this EFS file with each new release. Description: Corona Chart Cycle Period Version: 1.0 9/10/2008 Notes: The spectral content of the data are measured in a bank of contiguous filters as described in “Measuring Cycle Periods” in the March 2008 issue of Stocks & Commodities Magazine. The filter having the strongest output is selected as the current dominant cycle period. The cycle period is measured as the number of bars contained in one full cycle period. The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com. Formula Parameters: Default: View Line DC True **********************************/ var fpArray = new Array(); var bInit = false; var bVersion = null; function preMain() { setPriceStudy(false); setShowCursorLabel(false); setShowTitleParameters( false ); setStudyTitle("Corona Chart Cycle Period"); // Dominant Cycle properties setDefaultBarFgColor(Color.RGB(nLineR, nLineG, nLineB), 60); setDefaultBarThickness(3, 60); var x=0; fpArray[x] = new FunctionParameter("ViewLine", FunctionParameter.BOOLEAN); with(fpArray[x++]){ setName("View Line DC"); setDefault(true); } } var xResultArray = new Array(61); var nLineR = 255; var nLineG = 255; var nLineB = 0; var nFuzzR = 255; var nFuzzG = 0; var nFuzzB = 0; var bShowDC = true; var xPrice = null; var nRef_Global = 0; var ndelta = 0.1; var ngamma = 0; var nalpha = 0; var nbeta = 0; var nN = 0; var nPeriod = 0; var nMaxAmpl = 0; var nNum = 0; var nDenom = 0; var nDC = 0; var nDomCyc = 0; var nColor1 = 0; var nColor2 = 0; var nColor3 = 0; var nalpha1 = 0; var xHP = null; var nSmoothHP = 0; var nSmoothHP1 = 0; var aI = new Array(60); var aOldI = new Array(60); var aOlderI = new Array(60); var aQ = new Array(60); var aOldQ = new Array(60); var aOlderQ = new Array(60); var aReal = new Array(60); var aOldReal = new Array(60); var aOlderReal = new Array(60); var aImag = new Array(60); var aOldImag = new Array(60); var aOlderImag = new Array(60); var aAmpl = new Array(60); var aOldAmpl = new Array(60); var aDB = new Array(60); var aOldDB = new Array(60); var aDC = new Array(60); function main(ViewLine) { var nResCounter = 0; var nState = getBarState(); var pi = 3.1415926; var nCounter = 0; if (bVersion == null) bVersion = verify(); if (bVersion == false) return; if (nState == BARSTATE_ALLBARS) { resetVars(); } nalpha1 = (1 - (Math.sin(pi * (360 / 30) / 180)) / (Math.cos(pi * (360 / 30) / 180))); if (nState == BARSTATE_NEWBAR) nSmoothHP1 = nSmoothHP; if ( bInit == false ) { bShowDC = ViewLine; xPrice = hl2(); xHP = efsInternal("Calc_HP", xPrice, nalpha1); bInit = true; drawTextPixel( 10, 10,"Corona Chart Cycle Period", Color.black, null, Text.RELATIVETOLEFT | Text.RELATIVETOTOP, "Name" ,10, -10 ); } if (getCurrentBarCount() < 61) return; if (nState == BARSTATE_NEWBAR) { aDC.pop(); aDC.unshift(nDC); for (nN = 12; nN <= 60; nN++) { aOlderI[nN] = aOldI[nN]; aOldI[nN] = aI[nN]; aOlderQ[nN] = aOldQ[nN]; aOldQ[nN] = aQ[nN]; aOlderReal[nN] = aOldReal[nN]; aOldReal[nN] = aReal[nN]; aOlderImag[nN] = aOldImag[nN]; aOldImag[nN] = aImag[nN]; aOldAmpl[nN] = aAmpl[nN]; aOldDB[nN] = aDB[nN]; } } nSmoothHP = 0; if (xPrice.getValue(-1) != null) nSmoothHP = 0; else nSmoothHP = xPrice.getValue(0) - xPrice.getValue(-1); if (xHP.getValue(-5) != null) { nSmoothHP = (xHP.getValue(0) + 2 * xHP.getValue(-1) + 3 * xHP.getValue(-2) + 3 * xHP.getValue(-3) + 2 * xHP.getValue(-4) + xHP.getValue(-5)) / 12; } ndelta = (-0.015) * getCurrentBarCount() + 0.5; if (ndelta < 0.1) ndelta = 0.1; if (getCurrentBarCount() > 12) { for (nN = 12; nN <= 60; nN++) { nbeta = Math.cos(pi * (720 / nN) / 180); ngamma = 1 / Math.cos(pi * (1440 * ndelta / nN) / 180); nalpha = ngamma - Math.sqrt(ngamma * ngamma - 1); aQ[nN] = (0.5 * nN / 6.28318) * (nSmoothHP - nSmoothHP1); aI[nN] = nSmoothHP; aReal[nN] = 0.5 * (1 - nalpha) * (aI[nN] - aOlderI[nN]) + nbeta * (1 + nalpha) * aOldReal[nN] - nalpha * aOlderReal[nN]; aImag[nN] = 0.5 * (1 - nalpha) * (aQ[nN] - aOlderQ[nN]) + nbeta * (1 + nalpha) * aOldImag[nN] - nalpha * aOlderImag[nN]; aAmpl[nN] = (aReal[nN] * aReal[nN] + aImag[nN] * aImag[nN]); } } nMaxAmpl = aAmpl[12]; for (nN = 12; nN <= 60; nN++) { if (aAmpl[nN] > nMaxAmpl) nMaxAmpl = aAmpl[nN]; } for (nN = 12; nN <= 60; nN++) { if (nMaxAmpl != 0 && (aAmpl[nN] / nMaxAmpl) > 0) aDB[nN] = (-10) * Math.log(0.01 / (1 - 0.99 * aAmpl[nN] / nMaxAmpl)) / Math.log(10); aDB[nN] = 0.33 * aDB[nN] + 0.67 * aOldDB[nN]; if (aDB[nN] > 20) aDB[nN] = 20; } nNum = 0; nDenom = 0; for (nN = 12; nN <= 60; nN++) { if (aDB[nN] <= 6) { nNum = nNum + nN * (20 - aDB[nN]); nDenom = nDenom + (20 - aDB[nN]); } if (nDenom != 0) { nDC = 0.5 * nNum / nDenom; aDC[0] = nDC; } } nDomCyc = Median(aDC, 5); if (bShowDC == true) { xResultArray[60] = nDomCyc; } for (nN = 12; nN <= 60; nN++) { if (aDB[nN] <= 10) { nColor1 = Math.round(nLineR + aDB[nN] * (nFuzzR - nLineR) / 10); nColor2 = Math.round(nLineG + aDB[nN] * (nFuzzG - nLineG) / 10); nColor3 = Math.round(nLineB + aDB[nN] * (nFuzzB - nLineB) / 10); } if (aDB[nN] > 10) { nColor1 = Math.round(nFuzzR * (2 - aDB[nN] / 10)); nColor2 = Math.round(nFuzzG * (2 - aDB[nN] / 10)); nColor3 = Math.round(nFuzzB * (2 - aDB[nN] / 10)); } if (nN >= 12) { xResultArray[nResCounter++] = nN/2; setBarFgColor(Color.RGB(nColor1, nColor2, nColor3), nResCounter-1); setPlotType(PLOTTYPE_LINE, nResCounter-1); setDefaultBarThickness(5, nResCounter-1); } } return xResultArray; } function resetVars() { nRef_Global = 0; ndelta = 0.1; ngamma = 0; nalpha = 0; nbeta = 0; nN = 0; nPeriod = 0; nMaxAmpl = 0; nNum = 0; nDenom = 0; nDC = 0; nDomCyc = 0; nColor1 = 0; nColor2 = 0; nColor3 = 0; nalpha1 = 0; nSmoothHP = 0; nSmoothHP1 = 0; for (var i = 0; i < 61; i++) { xResultArray[i] = null; aI[i] = 0; aOldI[i] = 0; aOlderI[i] = 0; aQ[i] = 0; aOldQ[i] = 0; aOlderQ[i] = 0; aReal[i] = 0; aOldReal[i] = 0; aOlderReal[i] = 0; aImag[i] = 0; aOldImag[i] = 0; aOlderImag[i] = 0; aAmpl[i] = 0; aOldAmpl[i] = 0; aDB[i] = 0; aOldDB[i] = 0; aDC[i] = 0; } xResultArray[61] = null; return; } // calcHP globals var nPrevHP = null; var nCurrHP = null; function Calc_HP(x, nAlpha1) { 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 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=https://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; }--Jason KeckGO BACK
eSignal, a division of Interactive Data Corp.
800 815-8256,
www.esignalcentral.com
AMIBROKER: CORONA CHARTS
In the article "Corona Charts" in this issue, John Ehlers further develops his earlier work on market cycles. A new kind of indicator is presented that uses a glow-like effect to present another dimension of data. Implementation of corona charts in AmiBroker Formula Language (AFL) is based on earlier AmiBroker code that helps detect dominant cycles in data. We have added a new parameter that allows you to switch between spectrum charts and corona charts for swing positions. The formula is presented in Listing 1. To use it, simply enter the code in the AmiBroker Formula Editor, then choose the Tools->Apply Indicator menu from the editor. You can use the parameters window (available from the right-click menu) to set the period for the high-pass filter and to switch the chart type. A sample chart is shown in Figure 5.
FIGURE 5: AMIBROKER, CORONA CHART. The daily chart of SPY is shown in the upper pane with a corona swing chart in the lower pane. A corona is displayed when the market is in a trend and there is little cyclic component.LISTING 1
SetChartBkGradientFill( ColorRGB(0,0,0), ColorRGB(0,0,0)); PI = 3.1415926; Data = (H+L)/2; // detrending ( high-pass filter ) HFPeriods = Param("HP filter cutoff", 30, 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; MinPeriod = 6; MaxPeriod = 30; PeriodStep = 0.5; for( N = MinPeriod; N <= MaxPeriod; N += PeriodStep ) { beta = cos( 2 * PI / N ); Q = ( N / ( 2 * PI ) ) * SmoothHPDiff; for( bar = 12; bar < BarCount; bar++ ) { gamma = 1 / cos( 4 * PI * delta[ bar ] / N ); alpha = gamma - sqrt( gamma * gamma - 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 * Real + Imag * Imag; MaxAmpl = Max( MaxAmpl, Ampl ); VarSet("Ampl"+N, Ampl ); } CoronaSwingPos = ParamToggle("Chart Type", "Spectrum|Corona Swing Pos" ); // Plot Heat Map ( Spectrogram ) // and find dominant cycle DcNum = DcDenom = 0; for( N = MinPeriod; N <= MaxPeriod; N += PeriodStep ) { 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 CoronaSwingPos ) PlotOHLC( N, N, N-PeriodStep, N-PeriodStep, "", ColorRGB( Red, Green, 0 ), styleCloud | styleNoLabel); DcNum = DcNum + (db <= 6 ) * N * ( 20 - db ); DcDenom = DcDenom + ( db <= 6 ) * ( 20 - db ); } DC = DcNum / DcDenom; if( NOT CoronaSwingPos ) { DomCycle = Median( DC, 5 ); Plot( DomCycle, "Dominant Cycle", colorYellow); Title = EncodeColor( colorWhite ) + "{{NAME}} - Spectrum - DC " + DomCycle; } if( CoronaSwingPos ) { DomCycle = Median( DC, 5 ); DomCycle = Max( DomCycle, 6 ); BP2 = 0; DataDiff = Data - Ref( Data, -2 ); 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 ); BP2[ bar ] = 0.5 * ( 1 - alpha ) * DataDiff[ bar ] + beta * ( 1 + alpha ) * BP2[ bar - 1 ] - alpha * BP2[ bar - 2 ]; } Q2 = ( domCycle / ( 2 * PI ) ) * ( BP2 - Ref( BP2, -1 ) ); Lead60 = 0.5 * BP2 + 0.866 * Q2; HL = HHV( Lead60, 50 ); LL = LLV( Lead60, 50 ); Psn = ( Lead60 - LL )/( HL - LL ); HL = HHV( Psn, 20 ); LL = LLV( Psn, 20 ); Width = IIf( HL - LL > 0.85, 0.85, ( HL - LL ) ); for( N = 0; N < 50; N++ ) { Raster = log( Width/( 0.2 + abs( Psn - N/50 ) ) ); Raster = Min( 2, Max( 0, Raster ) ); CR = 128*Raster;//IIf( Raster <= 10, Raster, 255 - Raster ); y = 0.02 * N; PlotOHLC( y, y+0.01, y -0.01, y-0.01, "", ColorRGB( 0, CR, CR ), styleCloud | styleNoLabel ); } Plot( Psn, "", ColorRGB( 0, 255, 255 )); Title = EncodeColor( colorWhite ) + "{{NAME}} - Corona Swing Position " + Psn; } GraphZOrder = 1;--Tomasz Janeczko, AmiBroker.comGO BACK
www.amibroker.com
NEUROSHELL TRADER: CORONA CHARTS
John Ehlers's corona chart indicators can be easily implemented in NeuroShell Trader using NeuroShell Trader's ability to call functions written in standard languages like C, C++, Power Basic, or Delphi. Because the code for this tip is so lengthy, we have elected to use that facility instead of using our "point and click" Indicator Wizard. After moving the EasyLanguage code given in the article to your preferred compiler and creating a dynamic link library (DLL) from it, you can insert the resulting indicators as follows:
A sample chart is shown in Figure 6. Dynamic trading systems can be easily created in NeuroShell Trader by combining the corona chart indicators with the adaptive-length indicators available in John Ehlers's Cybernetic and Mesa8 NeuroShell Trader add-ons. Ehlers suggests that adaptive-length indicators linked to the cycle period indicator, when combined with NeuroShell Trader's genetic optimizer, could produce very robust systems. Similar strategies can also be created using the Dominant Cycle indicator found in John Ehlers's Mesa8 NeuroShell Trader Add-on. Users of NeuroShell Trader can go to the STOCKS & COMMODITIES section of the NeuroShell Trader free technical support website to download a copy of any Traders' Tip, including the compiled code we made for this article.
- Select "New Indicator..." from the Insert menu.
- Choose the External Program & Library Calls category.
- Select the appropriate External DLLL Call indicator.
- Set up the parameters to match your dynamic link library.
- Select the Finished button.
FIGURE 6: NEUROSHELL, CORONA CHART. Here is a sample NeuroShell chart demonstrating the corona charts indicators.--Marge Sherald, Ward Systems Group, Inc.GO BACK
301 662-7950, sales@wardsystems.com
www.neuroshell.com
WORDEN BROTHERS BLOCKS: THE MIDAS TOUCH
Note: To use the indicators and charts in this Traders' Tip, you will need the free Blocks software. Go to www.Blocks.com to download the software and get free US stock charts and scans. The MIDAS and I-MIDAS indicators from Andrew Coles's article in the September 2008 issue, "The Midas Touch," can be implemented in Blocks using RealCode. A sample chart is shown in Figure 7. RealCode is based on the Microsoft Visual Basic.Net framework and uses the Visual Basic (VB) language syntax. RealCode is compiled into a .Net assembly and run by the Blocks application. Unlike the scripting language that other trading applications use, RealCode is fully compiled and runs at the same machine language level as the Blocks application itself. This gives you unmatched performance running at the same speed as if we (the developers of Blocks) wrote the code ourselves, with the flexibility of "run-time development and assembly" that you get by writing your own custom code.
FIGURE 7: WORDEN BROTHERS BLOCKS, MIDAS CHARTS. Here, the MIDAS is applied to daily chart of AAPL. After you plot the first instance of MIDAS, you can right-click on the indicator, select "copy," then paste it into the pane again. Then adjust the color and date/time settings for each plot.To download the RealCode Reference manual as well as the Blocks software, go to www.Blocks.com.MIDAS/I-MIDAS code:
'# Year = UserInput.Integer = 2008 '# Month = UserInput.Integer = 1 '# Day = UserInput.Integer = 1 '# Leave the Hour, Minute, Second values set to 0 for MIDAS. '# Hour = UserInput.Integer = 0 '# Minute = UserInput.Integer = 0 '# Second = UserInput.integer = 0 Static StartDate As Date Static CumPrice As Double Static CumVolume As Double If isFirstBar Then StartDate = New Date(Year,Month,Day,Hour,Minute,Second) CumPrice = 0 CumVolume = 0 End If If CurrentDate >= StartDate Then CumPrice += Price.Last * Volume CumVolume += Volume Plot = CumPrice / CumVolume Else Plot = Single.NaN End If--Bruce Loebrich and Patrick ArgoGO BACK
Worden Brothers, Inc.
AIQ: MOCS EXIT INDICATOR
The AIQ code for Michael J. Carr's Mocs exit indicator from his August 2008 article, "Relative Strength As A Selling Tool," is given here. Using relative strength as an exit indicator can be very effective and is often overlooked when we are designing exits for our strategies. One exit strategy that uses relative strength is the MOCS exit, originally developed by Christopher Hendrix. As Carr discusses in his August 2008 article, the relative strength of the stock to the S&P 500 index (RS_SPX) is inserted into the MACD formula in place of the price. In coding the MACD of the RS_SPX, I generated three indicators as follows:
MOCS = 12-bar EMA of RS_SPX – 26 bar EMA of RS_SPX sigMOCS = 9-bar EMA of MOCS difMOCS = MOCS – sigMOCSI then used these indicators in various combinations to come up with three exits in addition to the one suggested by the author. The table in Figure 8 compares the results of a backtest of a 30-day breakout system on the NASDAQ 100 stocks from 10/11/02 to 9/12/08. LX1 is the exit mentioned in the article and is the fastest of the four exits. However, the best performing exit was LX2 which uses only the MOCS indicator and exits when it turns negative. The LX3 and LX4 exits are combinations of the MOCS and the difMocs. The slowest exits proved to be the ones with the best reward-to-risk ratios.!! RELATIVE STRENGTH AS A SELLING TOOL ! Author: Michael J. Carr, CMT, TASC Aug 2008 ! Coded by: Richard Denning 9/15/08 ! www.TradersEdgeSystems.com C is [close]. ! MOMENTUM OF COMPARATIVE STRENGTH (MOCS) RSspx is C / tickerUDF("SPX",C)*100000. RSema12 is expavg(RSspx,12). RSema26 is expavg(RSspx,26). ! MACD FORMULA APPLIED TO RS MOCS is RSema12 - RSema26. sigMOCS is expavg(MOCS,9). difMOCS is MOCS - sigMOCS. ! ENTRY RULES FOR TESTING EXITS: LE1 if C > highresult(C,30,1) and difMOCS > 0 and MOCS > 0. LE2 if LE1. LE3 if LE1. LE4 if LE1. ! VARIOUS EXITS USING MOCS: LX1 if difMOCS < 0. LX2 if MOCS < 0. LX3 if MOCS < 0 or countof(difMOCS < 0,6)=6 . LX4 if MOCS < 0 and countof(difMOCS < 0,6)=6 .The code can be downloaded from the AIQ website at www.aiqsystems.com and also from www.tradersedge systems.com/traderstips.htm.
FIGURE 8: AIQ, MOCS EXIT INDICATOR. Here is a comparison of four relative strength exits using the MOCS indicator. Exit LX2 had the best metrics compared to the other three approaches.--Richard DenningGO BACK
richard.denning@earthlink.net for AIQ Systems
TRADERSTUDIO: CORONA CHARTS
I have prepared TradersStudio code for John Ehlers's article in this issue, "Corona Charts." Figure 9 shows the four indicators as they appear on a QuickChart in TradersStudio. The corona effects do not show on the indicator panels but instead are shown on a color report, as seen in Figures 10 and 11. These two figures show the current values for the four indicators and also their relative signal strength, also known as the corona, as represented by the color of the report cell.
FIGURE 9: TRADERSTUDIO, CORONA CHARTS. Here are Ehlers's four indicators as shown on a chart of the emini S&P 500 futures contract.
FIGURE 10: TRADERSTUDIO, COLOR REPORT. Here is a color report on a portfolio of futures as of September 12, 2008.
FIGURE 11: TRADERSTUDIO, COLOR REPORT. Here is a color report on a portfolio of futures as of May 1, 2008.I ran the report for two different time periods on a small futures portfolio to show how the colors will differ. Figure 10 shows the status as of 9/12/2008 and Figure 11 shows the status as of 5/1/2008. This type of report allows one to quickly spot the markets that have the best combination of indicators and their respective colors, which represent the signal strength. The color key is as follows:
Light green = Strong signal with little or no fuzz Light yellow = Moderately strong signal with some fuzz Yellow = Weaker signal with more fuzz Yellow = Even weaker signal with even more fuzz Red = Very weak signal with a high level of fuzz White = No rating regarding signal strengthThe color levels and colors can be adjusted by the user by changing the parameters in the code. Note that the first column, which displays the dominant cycle period, does not have the color applied and hence it is all white.The code can be downloaded from the TradersStudio website at www.TradersStudio.com ->Traders Resources->FreeCode and also from www.TradersEdgeSystems.com/traderstips.htm.
TradersStudioCode DomCyc.txt Function EhlersDC(colorRGB) Dim price As BarArray, DC As BarArray Dim HP As BarArray, SmoothHP As BarArray Dim delta As BarArray, gamma As BarArray Dim alpha As BarArray, beta As BarArray Dim alpha1 As BarArray, MaxAmpl As BarArray Dim Num As BarArray, Denom As BarArray Dim DomCyc As BarArray Dim fuzzRGB, lineRGB, maxColorRGB Dim N, TScurrentBar, myDate Dim I As Array, OldI As Array, OlderI As Array Dim Q As Array, OldQ As Array, OlderQ As Array Dim Real As Array, OldReal As Array, OlderReal As Array Dim Imag As Array, OldImag As Array, OlderImag As Array Dim Ampl As Array, OldAmpl As Array Dim DB As Array, OldDB As Array Dim aDC As Array, color As Array ReDim (I, 61) ReDim (OldI, 61) ReDim (OlderI, 61) ReDim (Q, 61) ReDim (OldQ, 61) ReDim (OlderQ, 61) ReDim (Real, 61) ReDim (OldReal, 61) ReDim (OlderReal, 61) ReDim (Imag, 61) ReDim (OldImag, 61) ReDim (OlderImag, 61) ReDim (Ampl, 61) ReDim (OldAmpl, 61) ReDim (DB, 61) ReDim (OldDB, 61) ReDim (aDC,5) ReDim (color,61) If BarNumber=FirstBar Then gamma = 0 alpha = 0 beta = 0 N = 0 MaxAmpl = 0 Num = 0 Denom = 0 DC = 0 DomCyc = 0 alpha1 = 0 HP = 0 SmoothHP = 0 For N = 0 To 60 I[N] = 0 OldI[N] = 0 OlderI[N] = 0 Q[N] = 0 OldQ[N] = 0 OlderQ[N]=0 Real[N] = 0 OldReal[N] = 0 OlderReal[N] = 0 Imag[N] = 0 OldImag[N] = 0 OlderImag[N] = 0 Ampl[N] = 0 OldAmpl[N] = 0 DB[N] = 0 OldDB[N] = 0 color[N] = 0 Next End If price = (H+L)/2 delta = 0.1 fuzzRGB = 190 lineRGB = 255 TScurrentBar = CurrentBar + 1 myDate = FormatDateTime(Date) I = GValue201 OldI = GValue202 OlderI = GValue203 Q = GValue204 OldQ = GValue205 OlderQ = GValue206 Real = GValue207 OldReal = GValue208 OlderReal = GValue209 Imag = GValue210 OldImag = GValue211 OlderImag = GValue212 Ampl = GValue213 OldAmpl = GValue214 DB = GValue215 OldDB = GValue216 alpha1 = (1 - Sin(DegToRad(360/30))) / Cos(DegToRad(360/30)) HP = .5*(1 + alpha1)*(price - price[1]) + alpha1*HP[1] SmoothHP = (HP + 2*HP[1] + 3*HP[2] + 3*HP[3] + 2*HP[4] + HP[5]) / 12 If TScurrentBar < 7 Then SmoothHP = price - price[1] If TScurrentBar = 1 Then SmoothHP = 0 delta = -.015*(TScurrentBar) + .5 If delta < .1 Then delta = .1 If TScurrentBar > 12 Then For N = 12 To 60 beta = Cos(DegToRad(720 / N)) gamma = 1 / Cos(DegToRad(1440 * delta / N)) alpha = gamma - Sqr(gamma * gamma - 1) Q[N] = (.5*N / 6.28318)*(SmoothHP - SmoothHP[1]) I[N] = SmoothHP Real[N] = .5*(1 - alpha)*(I[N] - OlderI[N]) + beta*(1 + alpha)*OldReal[N] - alpha*OlderReal[N] Imag[N] = .5*(1 - alpha)*(Q[N] - OlderQ[N]) + beta*(1 + alpha)*OldImag[N] - alpha*OlderImag[N] Ampl[N] = (Real[N]*Real[N] + Imag[N]*Imag[N]) Next For N = 12 To 60 OlderI[N] = OldI[N] OldI[N] = I[N] OlderQ[N] = OldQ[N] OldQ[N] = Q[N] OlderReal[N] = OldReal[N] OldReal[N] = Real[N] OlderImag[N] = OldImag[N] OldImag[N] = Imag[N] OldAmpl[N] = Ampl[N] OldDB[N] = DB[N] Next MaxAmpl = Ampl[12] For N = 12 To 60 If Ampl[N] > MaxAmpl Then MaxAmpl = Ampl[N] Next For N = 12 To 60 If MaxAmpl <> 0 And (Ampl[N] / MaxAmpl) > 0 Then DB[N] = -10*Log(.01 / (1 - .99*Ampl[N] / MaxAmpl)) / Log(10) End If DB[N] = .33*DB[N] + .67*OldDB[N] If DB[N] > 20 Then DB[N] = 20 Next Num = 0 Denom = 0 For N = 12 To 60 If DB[N] <= 6 Then Num = Num + N*(20 - DB[N]) Denom = Denom + (20 - DB[N]) End If If Denom <> 0 Then DC = .5*Num / Denom Next For N = 0 To 4 aDC[N] = DC[N] Next DomCyc = Median(aDC) EhlersDC = DomCyc For N = 12 To 60 If DB[N] <= 10 Then color[N] = lineRGB + DB[N]*(fuzzRGB - lineRGB) / 10 If DB[N] > 10 Then color[N] = fuzzRGB*(2 - DB[N] / 10) If color[N] > maxColorRGB Then maxColorRGB = color[N] Next colorRGB = maxColorRGB End If GValue201 = I GValue202 = OldI GValue203 = OlderI GValue204 = Q GValue205 = OldQ GValue206 = OlderQ GValue207 = Real GValue208 = OldReal GValue209 = OlderReal GValue210 = Imag GValue211 = OldImag GValue212 = OlderImag GValue213 = Ampl GValue214 = OldAmpl GValue215 = DB GValue216 = OldDB End Function _________________________________________________________________________________________ Sub EhlersDomCycle() Dim colorRGB Dim EDC As BarArray Dim myDate myDate = FormatDateTime(Date) EDC = EhlersDC(colorRGB) plot1(EDC) End Sub _________________________________________________________________________________________ Function EhlersSP(byref colorRGB) Dim price As BarArray, DC As BarArray Dim HP As BarArray, SmoothHP As BarArray Dim delta As BarArray, gamma As BarArray Dim alpha As BarArray, beta As BarArray Dim alpha1 As BarArray, MaxAmpl As BarArray Dim Num As BarArray, Denom As BarArray Dim DomCyc As BarArray, gamma2 As BarArray Dim alpha2 As BarArray, beta2 As BarArray Dim delta2 As BarArray, BP2 As BarArray Dim Q2 As BarArray, Lead60 As BarArray Dim HL As BarArray, LL As BarArray Dim Psn As BarArray, Width As BarArray Dim fuzzRGB, lineRGB, maxColorRGB Dim N, TScurrentBar, myDate, count Dim I As Array, OldI As Array, OlderI As Array Dim Q As Array, OldQ As Array, OlderQ As Array Dim Real As Array, OldReal As Array, OlderReal As Array Dim Imag As Array, OldImag As Array, OlderImag As Array Dim Ampl As Array, OldAmpl As Array Dim DB As Array, OldDB As Array Dim Raster As Array, oldRaster As Array Dim aDC As Array, aRange As Array Dim color As Array ReDim (I, 61) ReDim (OldI, 61) ReDim (OlderI, 61) ReDim (Q, 61) ReDim (OldQ, 61) ReDim (OlderQ, 61) ReDim (Real, 61) ReDim (OldReal, 61) ReDim (OlderReal, 61) ReDim (Imag, 61) ReDim (OldImag, 61) ReDim (OlderImag, 61) ReDim (Ampl, 61) ReDim (OldAmpl, 61) ReDim (DB, 61) ReDim (OldDB, 61) ReDim (Raster, 51) ReDim (oldRaster, 51) ReDim (aDC,5) ReDim (aRange,5) ReDim (color,51) If BarNumber=FirstBar Then gamma = 0 alpha = 0 beta = 0 N = 0 MaxAmpl = 0 Num = 0 Denom = 0 DC = 0 DomCyc = 0 alpha1 = 0 HP = 0 SmoothHP = 0 gamma2 = 0 alpha2 = 0 beta2 = 0 delta2 = 0 BP2 = 0 Q2 = 0 Lead60 = 0 HL = 0 LL = 0 Psn = 0 Width = 0 For N = 0 To 60 I[N] = 0 OldI[N] = 0 OlderI[N] = 0 Q[N] = 0 OldQ[N] = 0 OlderQ[N]=0 Real[N] = 0 OldReal[N] = 0 OlderReal[N] = 0 Imag[N] = 0 OldImag[N] = 0 OlderImag[N] = 0 Ampl[N] = 0 OldAmpl[N] = 0 DB[N] = 0 OldDB[N] = 0 Next For N = 0 To 50 Raster[N] = 0 oldRaster[N] = 0 color[N] = 0 Next End If price = (H+L)/2 delta = 0.1 delta2 = 0.1 fuzzRGB = 190 lineRGB = 255 TScurrentBar = CurrentBar + 1 myDate = FormatDateTime(Date) I = GValue301 OldI = GValue302 OlderI = GValue303 Q = GValue304 OldQ = GValue305 OlderQ = GValue306 Real = GValue307 OldReal = GValue308 OlderReal = GValue309 Imag = GValue310 OldImag = GValue311 OlderImag = GValue312 Ampl = GValue313 OldAmpl = GValue314 DB = GValue315 OldDB = GValue316 Raster = Gvalue317 oldRaster = Gvalue318 alpha1 = (1 - Sin(DegToRad(360/30))) / Cos(DegToRad(360/30)) HP = .5*(1 + alpha1)*(price - price[1]) + alpha1*HP[1] SmoothHP = (HP + 2*HP[1] + 3*HP[2] + 3*HP[3] + 2*HP[4] + HP[5]) / 12 If TScurrentBar < 7 Then SmoothHP = price - price[1] If TScurrentBar = 1 Then SmoothHP = 0 delta = -0.015*(TScurrentBar) + 0.5 If delta < 0.1 Then delta = 0.1 If TScurrentBar > 12 Then 'begin concdition A For N = 12 To 60 beta = Cos(DegToRad(720 / N)) gamma = 1 / Cos(DegToRad(1440 * delta / N)) alpha = gamma - Sqr(gamma * gamma - 1) Q[N] = (.5*N / 6.28318)*(SmoothHP - SmoothHP[1]) I[N] = SmoothHP Real[N] = .5*(1 - alpha)*(I[N] - OlderI[N]) + beta*(1 + alpha)*OldReal[N] - alpha*OlderReal[N] Imag[N] = .5*(1 - alpha)*(Q[N] - OlderQ[N]) + beta*(1 + alpha)*OldImag[N] - alpha*OlderImag[N] Ampl[N] = (Real[N]*Real[N] + Imag[N]*Imag[N]) Next For N = 12 To 60 OlderI[N] = OldI[N] OldI[N] = I[N] OlderQ[N] = OldQ[N] OldQ[N] = Q[N] OlderReal[N] = OldReal[N] OldReal[N] = Real[N] OlderImag[N] = OldImag[N] OldImag[N] = Imag[N] OldAmpl[N] = Ampl[N] OldDB[N] = DB[N] Next For N = 1 To 50 oldRaster[N] = Raster[N] Next MaxAmpl = Ampl[12] For N = 12 To 60 If Ampl[N] > MaxAmpl Then MaxAmpl = Ampl[N] Next For N = 12 To 60 If MaxAmpl <> 0 And (Ampl[N] / MaxAmpl) > 0 Then DB[N] = -10*Log(.01 / (1 - .99*Ampl[N] / MaxAmpl)) / Log(10) End If DB[N] = .33*DB[N] + .67*OldDB[N] If DB[N] > 20 Then DB[N] = 20 Next Num = 0 Denom = 0 For N = 12 To 60 If DB[N] <= 6 Then Num = Num + N*(20 - DB[N]) Denom = Denom + (20 - DB[N]) End If If Denom <> 0 Then DC = .5*Num / Denom Next For N = 0 To 4 aDC[N] = DC[N] Next DomCyc = Median(aDC) If DomCyc < 6 Then DomCyc = 6 beta2 = Cos(DegToRad(360 / DomCyc)) gamma2 = 1 / Cos(DegToRad(720*delta2 / DomCyc)) alpha2 = gamma2 - Sqr(gamma2*gamma2 - 1) BP2 = 0.5*(1 - alpha2)*(price - price[2]) + beta2*(1 + alpha2)*BP2[1] - alpha2*BP2[2] Q2 = (DomCyc / 6.28318)*(BP2 - BP2[1]) Lead60 = 0.5*BP2 + 0.866*Q2 HL = Lead60 LL = Lead60 For count = 0 To 50 If Lead60[count] > HL Then HL = Lead60[count] If Lead60[count] < LL Then LL = Lead60[count] Next Psn = (Lead60 - LL) / (HL - LL) HL = Psn LL = Psn For count = 0 To 20 If Psn[count] > HL Then HL = Psn[count] If Psn[count] < LL Then LL = Psn[count] Next If HL - LL > 0.85 Then Width = 0.01 Else Width = 0.15*(HL - LL) EhlersSP = (10*Psn-5) For N = 1 To 50 Raster[N] = 20 If Width > 0 Then If N < Round(50*Psn,0) Then Raster[N] = 0.5*((((20*Psn - 0.4*N)/ Width) ^ 0.95) + 0.5*oldRaster[N]) If N > Round(50*Psn,0) Then Raster[N] = 0.5*((((-20*Psn + 0.4*N)/ Width) ^ 0.95) + 0.5*oldRaster[N]) End If If N = Round(50*Psn,0) Then Raster[N] = 0.5*oldRaster[N] If Raster[N] < 0 Then Raster[N] = 0 If Raster[N] > 20 Then Raster[N] = 20 If HL - LL > 0.8 Then Raster[N] = 20 oldRaster[N] = Raster[N] Next For N = 1 To 50 If Raster[N] <= 10 Then color[N] = lineRGB + Raster[N]*(fuzzRGB - lineRGB) / 10 End If If Raster[N] > 10 Then color[N] = fuzzRGB*(2 - Raster[N] / 10) End If If color[N] > maxColorRGB Then maxColorRGB = color[N] Next colorRGB = maxColorRGB End If 'end condition A GValue301 = I GValue302 = OldI GValue303 = OlderI GValue304 = Q GValue305 = OldQ GValue306 = OlderQ GValue307 = Real GValue308 = OldReal GValue309 = OlderReal GValue310 = Imag GValue311 = OldImag GValue312 = OlderImag GValue313 = Ampl GValue314 = OldAmpl GValue315 = DB GValue316 = OldDB Gvalue317 = Raster Gvalue318 = oldRaster End Function __________________________________________________________________________________________ Sub EhlersSwingPosition() Dim colorRGB Dim ESP As BarArray Dim myDate myDate = FormatDateTime(Date) ESP = EhlersSP(colorRGB) plot1(ESP) End Sub ____________________________________________________________________________________________ ' Function EhlersTV(byref colorRGB) Dim price As BarArray, DC As BarArray Dim HP As BarArray, SmoothHP As BarArray Dim delta As BarArray, gamma As BarArray Dim alpha As BarArray, beta As BarArray Dim alpha1 As BarArray, beta1 As BarArray Dim gamma1 As BarArray, delta1 As BarArray Dim alpha2 As BarArray, MaxAmpl As BarArray Dim Num As BarArray, Denom As BarArray Dim DomCyc As BarArray,IP As BarArray Dim Q1 As BarArray, ampl2 As BarArray Dim trend As BarArray, ratio As BarArray Dim TV As BarArray, width As BarArray Dim fuzzRGB, lineRGB, maxColorRGB Dim N, TScurrentBar, myDate Dim I As Array, OldI As Array, OlderI As Array Dim Q As Array, OldQ As Array, OlderQ As Array Dim Real As Array, OldReal As Array, OlderReal As Array Dim Imag As Array, OldImag As Array, OlderImag As Array Dim Ampl As Array, OldAmpl As Array Dim DB As Array, OldDB As Array Dim Raster As Array, oldRaster As Array Dim aDC As Array, color As Array ReDim (I, 61) ReDim (OldI, 61) ReDim (OlderI, 61) ReDim (Q, 61) ReDim (OldQ, 61) ReDim (OlderQ, 61) ReDim (Real, 61) ReDim (OldReal, 61) ReDim (OlderReal, 61) ReDim (Imag, 61) ReDim (OldImag, 61) ReDim (OlderImag, 61) ReDim (Ampl, 61) ReDim (OldAmpl, 61) ReDim (DB, 61) ReDim (OldDB, 61) ReDim (Raster, 51) ReDim (oldRaster, 51) ReDim (aDC,5) ReDim (color,51) If BarNumber=FirstBar Then gamma = 0 alpha = 0 beta = 0 delta = 0.1 alpha1 = 0 beta1 = 0 gamma1 = 0 delta1 = 0 alpha2 = 0 N = 0 MaxAmpl = 0 Num = 0 Denom = 0 DC = 0 DomCyc = 0 alpha1 = 0 HP = 0 SmoothHP = 0 IP = 0 Q1 = 0 ampl2 = 0 trend = 0 ratio = 0 TV = 0 width = 0 For N = 0 To 60 I[N] = 0 OldI[N] = 0 OlderI[N] = 0 Q[N] = 0 OldQ[N] = 0 OlderQ[N]=0 Real[N] = 0 OldReal[N] = 0 OlderReal[N] = 0 Imag[N] = 0 OldImag[N] = 0 OlderImag[N] = 0 Ampl[N] = 0 OldAmpl[N] = 0 DB[N] = 0 OldDB[N] = 0 Next For N = 0 To 50 Raster[N] = 0 oldRaster[N] = 0 color[N] = 0 Next End If price = (H+L)/2 delta1 = 0.1 fuzzRGB = 190 lineRGB = 255 TScurrentBar = CurrentBar + 1 myDate = FormatDateTime(Date) I = GValue501 OldI = GValue502 OlderI = GValue503 Q = GValue504 OldQ = GValue505 OlderQ = GValue506 Real = GValue507 OldReal = GValue508 OlderReal = GValue509 Imag = GValue510 OldImag = GValue511 OlderImag = GValue512 Ampl = GValue513 OldAmpl = GValue514 DB = GValue515 OldDB = GValue516 Raster = Gvalue517 oldRaster = Gvalue518 alpha1 = (1 - Sin(DegToRad(360/30))) / Cos(DegToRad(360/30)) HP = .5*(1 + alpha1)*(price - price[1]) + alpha1*HP[1] SmoothHP = (HP + 2*HP[1] + 3*HP[2] + 3*HP[3] + 2*HP[4] + HP[5]) / 12 If TScurrentBar < 7 Then SmoothHP = price - price[1] If TScurrentBar = 1 Then SmoothHP = 0 delta = -.015*(TScurrentBar) + .5 If delta < .1 Then delta = .1 If TScurrentBar > 12 Then 'begin condition A For N = 12 To 60 beta = Cos(DegToRad(720 / N)) gamma = 1 / Cos(DegToRad(1440 * delta / N)) alpha = gamma - Sqr(gamma * gamma - 1) Q[N] = (.5*N / 6.28318)*(SmoothHP - SmoothHP[1]) I[N] = SmoothHP Real[N] = .5*(1 - alpha)*(I[N] - OlderI[N]) + beta*(1 + alpha)*OldReal[N] - alpha*OlderReal[N] Imag[N] = .5*(1 - alpha)*(Q[N] - OlderQ[N]) + beta*(1 + alpha)*OldImag[N] - alpha*OlderImag[N] Ampl[N] = (Real[N]*Real[N] + Imag[N]*Imag[N]) Next For N = 12 To 60 OlderI[N] = OldI[N] OldI[N] = I[N] OlderQ[N] = OldQ[N] OldQ[N] = Q[N] OlderReal[N] = OldReal[N] OldReal[N] = Real[N] OlderImag[N] = OldImag[N] OldImag[N] = Imag[N] OldAmpl[N] = Ampl[N] OldDB[N] = DB[N] Next For N = 1 To 50 oldRaster[N] = Raster[N] Next MaxAmpl = Ampl[12] For N = 12 To 60 If Ampl[N] > MaxAmpl Then MaxAmpl = Ampl[N] Next For N = 12 To 60 If MaxAmpl <> 0 And (Ampl[N] / MaxAmpl) > 0 Then DB[N] = -10 * Log(0.01 / (1 - 0.99 * Ampl[N] / MaxAmpl)) / Log(10) End If DB[N] = .33*DB[N] + .67*OldDB[N] If DB[N] > 20 Then DB[N] = 20 Next Num = 0 Denom = 0 For N = 12 To 60 If DB[N] <= 6 Then Num = Num + N*(20 - DB[N]) Denom = Denom + (20 - DB[N]) End If If Denom <> 0 Then DC = .5*Num / Denom Next For N = 0 To 4 aDC[N] = DC[N] Next DomCyc = Median(aDC) If DomCyc < 6 Then DomCyc = 6 'Filter Bandpass component beta1 = Cos(DegToRad(360 / DomCyc)) gamma1 = 1 / Cos(DegToRad(720*delta1 / DomCyc) ) alpha2 = gamma1 - Sqr(gamma1*gamma1 - 1) IP = 0.5*(1 - alpha2)*(price - price[2]) + beta1*(1 + alpha2)*IP[1] - alpha2*IP[2] 'Quadrature component is derivative of InPhase component divided by omega Q1 = (DomCyc / 6.28318)*(IP - IP[1]) 'Pythagorean theorem to establish cycle amplitude ampl2 = Sqr(IP*IP + Q1*Q1) 'Trend amplitude taken over the cycle period trend = price - price[CInt(Round(DomCyc,0)) - 1] If trend <> 0 And ampl2 <> 0 Then ratio = 0.33 * trend / ampl2 + 0.67 * ratio[1] If ratio > 10 Then ratio = 10 If ratio < -10 Then ratio = -10 TV = 0.05 * (ratio + 10) If TV < 0.3 Or TV > 0.7 Then width = 0.01 If TV >= 0.3 And TV < 0.5 Then width = TV - 0.3 If TV > 0.5 And TV <= 0.7 Then width = -TV + 0.7 EhlersTV = (20*TV-10) For N = 1 To 50 Raster[N] = 20 If width > 0 Then If N < Round(50*TV,0) Then Raster[N] = 0.8*((((20*TV - 0.4*N)/ width) ^ 0.85) + 0.2*oldRaster[N]) End If If N > Round(50*TV,0) Then Raster[N] = 0.8*((((-20*TV + 0.4*N)/ width) ^ 0.85) + 0.2*oldRaster[N]) End If End If If N = Round(50*TV,0) Then Raster[N] = 0 + 0.5*oldRaster[N] If Raster[N] < 0 Then Raster[N] = 0 If Raster[N] > 20 Or TV < 0.3 Or TV > 0.7 Then Raster[N] = 20 Next For N = 1 To 50 If Raster[N] <= 10 Then color[N] = lineRGB + Raster[N]*(fuzzRGB - lineRGB) / 10 End If If Raster[N] > 10 Then color[N] = fuzzRGB*(2 - Raster[N] / 10) End If If color[N] > maxColorRGB Then maxColorRGB = color[N] Next colorRGB = maxColorRGB End If 'end condition A GValue501 = I GValue502 = OldI GValue503 = OlderI GValue504 = Q GValue505 = OldQ GValue506 = OlderQ GValue507 = Real GValue508 = OldReal GValue509 = OlderReal GValue510 = Imag GValue511 = OldImag GValue512 = OlderImag GValue513 = Ampl GValue514 = OldAmpl GValue515 = DB GValue516 = OldDB Gvalue517 = Raster Gvalue518 = oldRaster End Function __________________________________________________________________________________ sub EhlersTrendVigor() Dim colorRGB Dim ETV As BarArray Dim myDate myDate = FormatDateTime(Date) ETV = EhlersTV(colorRGB) plot1(ETV) End Sub __________________________________________________________________________________ Sub ColorSignalStrength() Dim color1, color2, color3,color4 Dim colorRGB1, colorRGB2, colorRGB3, colorRGB4 Dim EDC As BarArray, ESP As BarArray Dim ESNR As BarArray, ETV As BarArray Dim myDate myDate = FormatDateTime(Date) EDC = EhlersDC(colorRGB1) ESP = EhlersSP(colorRGB2) ESNR = EhlersSNR(colorRGB3) ETV = EhlersTV(colorRGB4) color1 = "white" color2 = "white" color3 = "white" color4 = "white" 'note Dominate Cycle does not have a color change; ' it uses color1 and it will always be white If colorRGB2 >= 190 And colorRGB2 < 210 Then color2 = "LightYellow" Else If colorRGB2 >= 200 And colorRGB2 < 220 Then color2 = "Yellow" Else If colorRGB2 >= 220 Then color2 = "Red" Else color2 = "LightGreen" End If End If End If If colorRGB3 >= 190 And colorRGB3 < 210 Then color3 = "LightYellow" Else If colorRGB3 >= 200 And colorRGB3 < 220 Then color3 = "Yellow" Else If colorRGB3 >= 220 Then color3 = "Red" Else color3 = "LightGreen" End If End If End If If colorRGB4 >= 190 And colorRGB4 < 210 Then color4 = "LightYellow" Else If colorRGB4 >= 200 And colorRGB4 < 220 Then color4 = "Yellow" Else If colorRGB4 >= 220 Then color4 = "Red" Else color4 = "LightGreen" End If End If End If ColorReport("DominateCycle",CStr(Round(EDC,2)),color1) ColorReport("SwingPosition",CStr(Round(ESP,2)), color2) ColorReport("SigToNoiseR",CStr(Round(ESNR,2)), color3) ColorReport("TrendVigor",CStr(Round(ETV,2)), color4) End Sub _______________________________________________________________________ Function EhlersSNR(ByRef colorRGB) Dim price As BarArray, DC As BarArray Dim HP As BarArray, SmoothHP As BarArray Dim delta As BarArray, gamma As BarArray Dim alpha As BarArray, beta As BarArray Dim alpha1 As BarArray, MaxAmpl As BarArray Dim Num As BarArray, Denom As BarArray Dim DomCyc As BarArray, avg1 As BarArray Dim sigNR As BarArray, signal As BarArray Dim noise As BarArray, width As BarArray Dim fuzzRGB, lineRGB, maxColorRGB Dim N, TScurrentBar, myDate Dim I As Array, OldI As Array, OlderI As Array Dim Q As Array, OldQ As Array, OlderQ As Array Dim Real As Array, OldReal As Array, OlderReal As Array Dim Imag As Array, OldImag As Array, OlderImag As Array Dim Ampl As Array, OldAmpl As Array Dim DB As Array, OldDB As Array Dim Raster As Array, oldRaster As Array Dim aDC As Array, aRange As Array Dim color As Array ReDim (I, 61) ReDim (OldI, 61) ReDim (OlderI, 61) ReDim (Q, 61) ReDim (OldQ, 61) ReDim (OlderQ, 61) ReDim (Real, 61) ReDim (OldReal, 61) ReDim (OlderReal, 61) ReDim (Imag, 61) ReDim (OldImag, 61) ReDim (OlderImag, 61) ReDim (Ampl, 61) ReDim (OldAmpl, 61) ReDim (DB, 61) ReDim (OldDB, 61) ReDim (Raster, 51) ReDim (oldRaster, 51) ReDim (aDC,5) ReDim (aRange,5) ReDim (color,51) If BarNumber=FirstBar Then gamma = 0 alpha = 0 beta = 0 N = 0 MaxAmpl = 0 Num = 0 Denom = 0 DC = 0 DomCyc = 0 alpha1 = 0 HP = 0 SmoothHP = 0 avg1 = 0 signal = 0 noise = 0 sigNR = 0 width = 0 For N = 0 To 60 I[N] = 0 OldI[N] = 0 OlderI[N] = 0 Q[N] = 0 OldQ[N] = 0 OlderQ[N]=0 Real[N] = 0 OldReal[N] = 0 OlderReal[N] = 0 Imag[N] = 0 OldImag[N] = 0 OlderImag[N] = 0 Ampl[N] = 0 OldAmpl[N] = 0 DB[N] = 0 OldDB[N] = 0 Next For N = 0 To 50 Raster[N] = 0 oldRaster[N] = 0 color[N] = 0 Next End If price = (H+L)/2 delta = 0.1 fuzzRGB = 190 lineRGB = 255 TScurrentBar = CurrentBar + 1 myDate = FormatDateTime(Date) I = GValue401 OldI = GValue402 OlderI = GValue403 Q = GValue404 OldQ = GValue405 OlderQ = GValue406 Real = GValue407 OldReal = GValue408 OlderReal = GValue409 Imag = GValue410 OldImag = GValue411 OlderImag = GValue412 Ampl = GValue413 OldAmpl = GValue414 DB = GValue415 OldDB = GValue416 Raster = Gvalue417 oldRaster = Gvalue418 alpha1 = (1 - Sin(DegToRad(360/30))) / Cos(DegToRad(360/30)) HP = .5*(1 + alpha1)*(price - price[1]) + alpha1*HP[1] SmoothHP = (HP + 2*HP[1] + 3*HP[2] + 3*HP[3] + 2*HP[4] + HP[5]) / 12 If TScurrentBar < 7 Then SmoothHP = price - price[1] If TScurrentBar = 1 Then SmoothHP = 0 delta = -.015*(TScurrentBar) + .5 If delta < .1 Then delta = .1 If TScurrentBar > 12 Then 'begin condition A For N = 12 To 60 beta = Cos(DegToRad(720 / N)) gamma = 1 / Cos(DegToRad(1440 * delta / N)) alpha = gamma - Sqr(gamma * gamma - 1) Q[N] = (.5*N / 6.28318)*(SmoothHP - SmoothHP[1]) I[N] = SmoothHP Real[N] = .5*(1 - alpha)*(I[N] - OlderI[N]) + beta*(1 + alpha)*OldReal[N] - alpha*OlderReal[N] Imag[N] = .5*(1 - alpha)*(Q[N] - OlderQ[N]) + beta*(1 + alpha)*OldImag[N] - alpha*OlderImag[N] Ampl[N] = (Real[N]*Real[N] + Imag[N]*Imag[N]) Next For N = 12 To 60 OlderI[N] = OldI[N] OldI[N] = I[N] OlderQ[N] = OldQ[N] OldQ[N] = Q[N] OlderReal[N] = OldReal[N] OldReal[N] = Real[N] OlderImag[N] = OldImag[N] OldImag[N] = Imag[N] OldAmpl[N] = Ampl[N] OldDB[N] = DB[N] Next For N = 1 To 50 oldRaster[N] = Raster[N] Next MaxAmpl = Ampl[12] For N = 12 To 60 If Ampl[N] > MaxAmpl Then MaxAmpl = Ampl[N] Next For N = 12 To 60 If MaxAmpl <> 0 And (Ampl[N] / MaxAmpl) > 0 Then DB[N] = -10 * Log(0.01 / (1 - 0.99 * Ampl[N] / MaxAmpl)) / Log(10) End If DB[N] = .33*DB[N] + .67*OldDB[N] If DB[N] > 20 Then DB[N] = 20 Next Num = 0 Denom = 0 For N = 12 To 60 If DB[N] <= 6 Then Num = Num + N*(20 - DB[N]) Denom = Denom + (20 - DB[N]) End If If Denom <> 0 Then DC = .5*Num / Denom Next For N = 0 To 4 aDC[N] = DC[N] Next DomCyc = Median(aDC) If DomCyc < 6 Then DomCyc = 6 avg1 = 0.1 * price + 0.9 * avg1[1] If avg1 <> 0 And MaxAmpl > 0 Then signal = 0.2* Sqr(MaxAmpl) + 0.9 * signal[1] For N = 0 To 4 aRange[N] = H[N]-L[N] Next If avg1 <> 0 And TScurrentBar > 5 Then noise = 0.1 * Median(aRange) + 0.9 * noise[1] If signal <> 0 And noise <> 0 Then sigNR = 20 * Log(signal / noise) / Log(10) + 3.5 If sigNR < 1 Then sigNR = 0 If sigNR > 11 Then sigNR = 10 sigNR = 0.1 * sigNR width = -0.4 * sigNR + 0.2 If sigNR > 0.5 Then width = 0 EhlersSNR = (10*sigNR+1) For N = 1 To 50 Raster[N] = 20 If width > 0 Then If N < Round(50*sigNR,0) Then Raster[N] = 0.5*( ( ( (20*sigNR - 0.4*N) / width) ^ 0.8 ) + oldRaster[N] ) End If If N > Round(50*sigNR, 0) And (0.4*N - 20*sigNR) / width > 1 Then Raster[N] = 0.5*( ( ( (-20*sigNR + .4*N)/width) ^ 0.8 ) + oldRaster[N] ) end if End If If N = Round(50*sigNR,0) Then Raster[N] = 0 + 0.5*oldRaster[N] If Raster[N] < 0 Then Raster[N] = 0 If Raster[N] > 20 Then Raster[N] = 20 If sigNR > 0.5 Then Raster[N] = 20 Next For N = 1 To 50 If Raster[N] <= 10 Then color[N] = lineRGB + Raster[N]*(fuzzRGB - lineRGB) / 10 End If If Raster[N] > 10 Then color[N] = fuzzRGB*(2 - Raster[N] / 10) End If If color[N] > maxColorRGB Then maxColorRGB = color[N] Next colorRGB = maxColorRGB End If 'end condition A GValue401 = I GValue402 = OldI GValue403 = OlderI GValue404 = Q GValue405 = OldQ GValue406 = OlderQ GValue407 = Real GValue408 = OldReal GValue409 = OlderReal GValue410 = Imag GValue411 = OldImag GValue412 = OlderImag GValue413 = Ampl GValue414 = OldAmpl GValue415 = DB GValue416 = OldDB Gvalue417 = Raster Gvalue418 = oldRaster End Function _______________________________________________________________________________________ sub EhlersSigNoise() Dim colorRGB Dim ESNR As BarArray Dim myDate myDate = FormatDateTime(Date) ESNR = EhlersSNR(colorRGB) plot1(ESNR) End Sub _______________________________________________________________________________________--Richard DenningGO BACK
richard.denning@earthlink.net
for TraderStudio, www.TradersStudio.com
TRADE IDEAS: FADING THE MARKET
"With globalization, the big [countries] don't eat the small; the fast eat the slow." Thomas L. Friedman (Op-Ed column, The New York Times, February 2, 2001)Friedman's observation easily applies to traders. For this month's Traders' Tip, we've provided a strategy that uses speed to uncover a backtested and winning advantage in this volatile market. It's based on the Trade Ideas inventory of alerts and filters, and it's backtested with trading rules modeled in The OddsMaker.This strategy fades certain movements to take advantage of our market view that today's markets are -- and will continue to be -- very volatility. Our hypothesis, given this view of the market, states that stocks moving up at least 75 cents in the last minute tend to be lower over the next 15 minutes. The idea is to put short offers out at the time of the alert.
Please note: If certain categories of stocks are excluded from short sales by the government, simply create a short sell exclusion list.
A video describing how to edit symbol lists appears here: https://www.trade-ideas.com/VideoHelp/Menu.html?video=Trade-Ideas%20Pro:%20Symbol%20List%20Editor This strategy also appears on the Trade Ideas blog at https://marketmovers.blogspot.com/.
FIGURE 12: TRADE IDEAS. Here is the Trade Ideas PRO strategy configuration for the strategy named "Overextended up move."Backtest this strategy using The OddsMaker with the trade rules shown in Figure 13. The results (last backtested for the period of 9/1/2008 to 9/19/2008) are shown in Figure 14.Description: "Over Extended Up Move"
Provided by: Trade Ideas (copyright © Trade Ideas LLC 2008). All rights reserved. This sample Trade Ideas strategy and its configuration are for educational purposes only and may be modified to further reflect a trading plan. Remember that these set-ups are sketches meant to give an idea how to model a trading plan. Use this "as is" or modify it as many others do. Know, however, that Trade-Ideas.com and all individuals affiliated with this site assume no responsibilities for trading and investment results. The indicators, alerts and all other features are for research purposes only and should not be construed as investment advice. Copy the following string directly into Trade Ideas PRO using the "Collaborate" feature (right-click in any strategy window): https://www.trade-ideas.com/View.php?O=20000000000000000000000000000000000000000000000000000000 _1D_0&QRUN=0.75&MaxPrice=300&MaxSpread=5&MinDNbbo=0.1&MinPrice=10&MinRV=3&MinVol=500000&WN=Over+Extended+Up+Move where one alert and six filters are used with the following specific settings:
- Running up now: 0.75 ($)
- Min price = 10 ($)
- Max price = 300 ($)
- Max spread = 5 (pennies)
- Min distance from inside market = 0.1 (%)
- Min daily volume = 500,000 (shares/day)
- Min current volume = 3 (ratio)
FIGURE 13: TRADE IDEAS, BACKTESTING. The trade rules for the strategy are shown here. You can use the The OddsMaker facility in Trade Ideas to backtest the strategy.
FIGURE 14: TRADE IDEAS, BACKTEST RESULTS. Here are sample results from backtesting the "Overextended Up Move" strategy. Results shown here are for the period 9/1/2008 to 9/19/2008.The Trade Ideas manual at https://www.trade-ideas.com/OddsMaker/Help.html can help you understand these backtest results from The OddsMaker component of our software.
--Dan MirkinGO BACK
Trade Ideas, LLC
www.trade-ideas.com, dan@trade-ideas.com
VT TRADER: GUPPY MULTIPLE MOVING AVERAGE (GMMA)
For this month's Traders' Tip, we're revisiting two articles by Daryl Guppy and Chen Jing titled "True Price Value" and "Parallel Listings And True Price Value" from the April 2008 and May 2008 issues of STOCKS & COMMODITIES, respectively.
In those two articles, Guppy and Jing discuss the role that psychological trading behavior plays in the relationship between price and value (and the trend patterns it creates) using examples from the Chinese and Hong Kong markets.
The Guppy multiple moving average (GMMA) is used for their market trend analysis. We'll be offering the GMMA indicator for download in our user forums. The VT Trader code and instructions for creating the GMMA indicator are as follows:
The Guppy Multiple Moving Average (GMMA) Indicator
1. Navigator Window>Tools>Indicator Builder>[New] button 2. In the Indicator Bookmark, type the following text for each field:Name: TASC TASC - 11/2008 - Guppy Multiple Moving Average (GMMA) Short Name: vt_GMMA Label Mask: 11/2008 - Guppy Multiple Moving Average (GMMA) Placement: Price Frame Inspect Alias: Guppy MMA3. In the Input Bookmark, create the following variables:[New] button... Name: MaPrice , Display Name: GMMA Price , Type: price , Default: close [New] button... Name: MaType , Display Name: GMMA MA Type , Type: MA Type, Default: Exponential4. In the Output Bookmark, create the following variables:[New] button... Var Name: ShortMA1 Name: (ShortMA1) Line Color: blue Line Width: thin Line Type: solid [New] button... Var Name: ShortMA2 Name: (ShortMA2) Line Color: blue Line Width: thin Line Type: solid [New] button... Var Name: ShortMA3 Name: (ShortMA3) Line Color: blue Line Width: thin Line Type: solid [New] button... Var Name: ShortMA4 Name: (ShortMA4) Line Color: blue Line Width: thin Line Type: solid [New] button... Var Name: ShortMA5 Name: (ShortMA5) Line Color: blue Line Width: thin Line Type: solid [New] button... Var Name: ShortMA6 Name: (ShortMA6) Line Color: blue Line Width: thi Line Type: solid [New] button... Var Name: LongMA1 Name: (LongMA1) Line Color: red Line Width: thin Line Type: solid [New] button... Var Name: LongMA2 Name: (LongMA2) Line Color: red Line Width: thin Line Type: solid [New] button... Var Name: LongMA3 Name: (LongMA3) Line Color: red Line Width: thin Line Type: solid [New] button... Var Name: LongMA4 Name: (LongMA4) Line Color: red Line Width: thin Line Type: solid [New] button... Var Name: LongMA5 Name: (LongMA5) Line Color: red Line Width: thin Line Type: solid [New] button... Var Name: LongMA6 Name: (LongMA6) Line Color: red Line Width: thin Line Type: solid5. In the Formula Bookmark, copy and paste the following formula:{Provided By: Visual Trading Systems, LLC & Capital Market Services, LLC (c) Copyright 2008} {Description: Guppy Multiple Moving Average (GMMA)} {Notes: T.A.S.C., April 2008 "Similar but Different, True Price Value" by Daryl Guppy and Chen Jing} {Notes: T.A.S.C., May 2008 "Parallel Listings and True Price Value" by Daryl Guppy and Chen Jing} {vt_GMMA Version 1.0} {Short-Term Moving Averages} ShortMA1:= mov(MaPrice,3,MaType); ShortMA2:= mov(MaPrice,5,MaType); ShortMA3:= mov(MaPrice,8,MaType); ShortMA4:= mov(MaPrice,10,MaType); ShortMA5:= mov(MaPrice,12,MaType); ShortMA6:= mov(MaPrice,15,MaType); {Long-Term Moving Averages} LongMA1:= mov(MaPrice,30,MaType); LongMA2:= mov(MaPrice,35,MaType); LongMA3:= mov(MaPrice,40,MaType); LongMA4:= mov(MaPrice,45,MaType); LongMA5:= mov(MaPrice,50,MaType); LongMA6:= mov(MaPrice,60,MaType);6. Click the "Save" icon to finish building the GMMA indicator. FIGURE 15: VT TRADER, GUPPY MULTIPLE MOVING AVERAGE. Here, the GMMA is attached to a EUR/USD daily candle chart.To attach the indicator to a chart, activate the chart window's contextual menu and select "Add Indicator." Select "Tasc - 11/2008 -- Guppy Multiple Moving Average (GMMA)" from the indicator list and click Add. A sample chart is shown in Figure 15.
To learn more about VT Trader, visit www.cmsfx.com.--Chris SkidmoreGO BACK
Visual Trading Systems, LLC (courtesy of CMS Forex)
(866) 51-CMSFX, trading@cmsfx.com
www.cmsfx.com
Return to November 2008 Contents
Originally published in the November 2008 issue of Technical Analysis of STOCKS & COMMODITIES magazine. All rights reserved. © Copyright 2008, Technical Analysis, Inc.