using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators;namespace WealthLab.Strategies { public class MyStrategy : WealthScript { 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; } public DataSeries CycleFilterDC(DataSeries ds, out DataSeries sine, out DataSeries cosine) { double twoPi = 2 * Math.PI; // Initialize arrays ArrayHolder">51"> ah = new ArrayHolder[51; for( int n = 8; n < 51; n++ ) ahn = new ArrayHolder(); Color">21"> color = new Color[21; DataSeries">51"> DB = new DataSeries[51; double domCycle = 0d; string name = ds.Description; DataSeries result = Close - Close; result.Description = "Dominant Cycle(" + name + ")"; // Create and plot the decibel series - change the colors later ChartPane dbPane = CreatePane(40, false, false ); for( int n = 8; n < 51; n++ ) { DBn = result + n; DBn.Description = "Cycle." + n.ToString(); PlotSeries(dbPane, DBn, Color.Black, LineStyle.Solid, 6); } // Convert decibels to RGB color for display for( int n = 0; n <= 10; n++ ) // yellow to red: 0 to 10 dB colorn = Color.FromArgb(255, (int)(255 - (255 * n / 10)), 0); for( int n = 11; n <= 20; n++ ) // red to black: 11 to 20 db colorn = Color.FromArgb( (int)(255 * (20 - n)/10 ), 0, 0); // Detrend data by High Pass Filtering with a 40 Period cutoff DataSeries HP = result; double alpha = (1 - Math.Sin(twoPi/40)) / Math.Cos(twoPi/40); for(int bar = 1; bar < Bars.Count; bar++) HPbar = 0.5 * (1 + alpha)* Momentum.Series(ds, 1)bar + alpha * HPbar-1; DataSeries smoothHP = FIR.Series(HP, "1,2,3,3,2,1"); for( int bar = 6; bar < Bars.Count; bar++ ) { double maxAmpl = 0; double delta = -0.015 * bar + 0.5; delta = delta < 0.15 ? 0.15 : delta; for( int n = 8; n < 51; n++ ) { double beta = Math.Cos(twoPi / n); double g = 1 / Math.Cos(2 * twoPi * delta / n); double a = g - Math.Sqrt(g * g - 1); ahn.Q = Momentum.Series(smoothHP, 1)bar * n / twoPi; ahn.I = smoothHPbar; ahn.R = 0.5 * (1 - a) * (ahn.I - ahn.I3) + beta * (1 + a) * ahn.R2 - a * ahn.R3; ahn.Im = 0.5 * (1 - a) * (ahn.Q - ahn.Q3) + beta * (1 + a) * ahn.Im2 - a * ahn.Im3; ahn.A = ahn.R * ahn.R + ahn.Im * ahn.Im; maxAmpl = ahn.A > maxAmpl ? ahn.A : maxAmpl; } double num = 0; double den = 0; for( int n = 8; n < 51; n++ ) { if( maxAmpl != 0 && ahn.A / maxAmpl > 0 ) ahn.dB = 10 * Math.Log10( (1 - 0.99 * ahn.A / maxAmpl) / 0.01 ); ahn.dB = ahn.dB > 20 ? 20 : ahn.dB; SetSeriesBarColor(bar, DBn, color(int)Math.Round(ah[n.dB)" title="n" title="(int)Math.Round(ah[n">(int)Math.Round(ah[n.dB)">n" title="(int)Math.Round(ah[n">(int)Math.Round(ah[n.dB)); if( ahn.dB <= 3 ) { num = num + n * (20 - ahn.dB); den = den + (20 - ahn.dB); } if( den > 0 ) domCycle = num/den; resultbar = domCycle; ahn.I3 = ahn.I2; ahn.I2 = ahn.I; ahn.Q3 = ahn.Q2; ahn.Q2 = ahn.Q; ahn.R3 = ahn.R2; ahn.R2 = ahn.R; ahn.Im3 = ahn.Im2; ahn.Im2 = ahn.Im; } } result = Median.Series(result, 10); PlotSeries(dbPane, result, Color.Lime, WealthLab.LineStyle.Solid, 2); // sine and cosine components sine = Low - Low; sine.Description = "sine(DC)"; double a2 = 0d; for(int bar = 10; bar < Bars.Count; bar++) { double delta = -0.015 * bar + 0.5; delta = delta < 0.15 ? 0.15 : delta; double beta = Math.Cos(2 * Math.PI / resultbar ); double g = 1 / Math.Cos(4 * Math.PI * delta / resultbar); if( g < 1 ) a2 = 0; else a2 = g - Math.Sqrt(g * g - 1); sinebar = 0.5 * (1 - a2) * Momentum.Value(bar, smoothHP, 1) + beta * (1 + a2) * sinebar-1 - a2 * sinebar-2; } cosine = ( result / 6.28 ) * ( sine - (sine >> 1) ); cosine.Description = "cosine(DC)"; ChartPane sinePane = CreatePane( 40, false, false ); for(int bar = 0; bar < Bars.Count; bar++) SetPaneBackgroundColor(sinePane, bar, Color.Black); PlotSeries(sinePane, sine, Color.Red, LineStyle.Solid, 1); PlotSeries(sinePane, cosine, Color.Cyan, LineStyle.Solid, 1); return result; } protected override void Execute() { HideVolume(); HidePaneLines(); DataSeries avgPrice = (High + Low) / 2; avgPrice.Description = "Avg Price"; // Get the dominant cycle, sine and cosine, and plot the heat map DataSeries sine, cosine; DataSeries DC = CycleFilterDC(avgPrice, out sine, out cosine); /* Use the DC, sine, and cosine DataSeries in a Trading Strategy here */ } } }