# TASC 2010-03 | Empirical Mode Decomposition (Ehlers, Way)

Modified on 2010/09/12 11:37 by Eugene — Categorized as: TASC Traders Tips

### Traders' Tip text

We combined the ideas and indicators from the article into a single script with a sample strategy in C# for Wealth-Lab 6. While you can probably think of a dozen ways to use the cycle mode indicator and its thresholds, the sample strategy enters long trades when the cycle turns up within the threshold zone and exits on a closing profit of 4% or after 5 bars. The time-based exit was chosen purposely to be a ΒΌ cycle to exit before the next turn down. The Strategy produced a slightly-positive win rate and raw profit factor for the last 6 years of trading on the Dow 30 and Nasdaq 100 index components.

Figure 1. Representative trades from the sample Strategy.

### WealthScript Code (C#)

```using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators;namespace WealthLab.Strategies { public class EmpiricalModeDecomp : WealthScript { StrategyParameter _period; StrategyParameter _delta; StrategyParameter _fraction; public EmpiricalModeDecomp() { _period = CreateParameter("Period", 20, 5, 50, 1); _delta = CreateParameter("Delta", 0.5, 0.05, 1, 0.05); _fraction = CreateParameter("Fraction", 0.25, 0.1, 1, 0.05); } public DataSeries BandPassSeries(DataSeries ds, int period, double delta) { DataSeries res = new DataSeries(ds, "BandPassSeries(" + ds.Description + "," + period + "," + delta + ")"); double beta = Math.Cos(2 * Math.PI / period); double gamma = 1/ Math.Cos(4 * Math.PI * delta / period); double alpha = gamma - Math.Sqrt(gamma * gamma - 1d); for (int bar = 2; bar < ds.Count; bar++) { resbar = 0.5 * (1 - alpha) * (dsbar - dsbar - 2) + beta * (1 + alpha) * resbar - 1 - alpha * resbar - 2; } return res; } protected override void Execute() { int per = _period.ValueInt; double delta = _delta.Value; double fraction = _fraction.Value; DataSeries bp = BandPassSeries(AveragePrice.Series(Bars), per, delta); DataSeries ema = EMA.Series(Close, 100, EMACalculation.Modern); DataSeries mean = SMA.Series(bp, 2 * per); mean.Description = "SMA(" + bp.Description + "," + 2 * per + ")"; DataSeries peak = new DataSeries(Bars, "peak()"); DataSeries valley = new DataSeries(Bars, "valley()"); double pk = 0d; double v = 0d; for(int bar = 2; bar < Bars.Count; bar++) { if( bpbar-1 > bpbar && bpbar-1 > bpbar-2 ) pk = bpbar - 1; if( bpbar-1 < bpbar && bpbar-1 < bpbar-2 ) v = bpbar-1; peakbar = pk; valleybar = v; } int avgPer = (int)(2.5 * per); DataSeries avgPeak = fraction * SMA.Series(peak, avgPer); DataSeries avgValley = fraction * SMA.Series(valley, avgPer); ChartPane cp = CreatePane( 40, true, false ); DrawHorzLine(cp, 0d, Color.Black, LineStyle.Dashed, 1); PlotSeries(PricePane, ema, Color.Black, LineStyle.Solid, 1); PlotSeries(cp, avgPeak, Color.DodgerBlue, LineStyle.Solid, 1); PlotSeries(cp, avgValley, Color.DodgerBlue, LineStyle.Solid, 1); PlotSeries(cp, mean, Color.Orange, LineStyle.Solid, 2); /* Sample Trading Strategy */ for (int bar = 2 * 100; bar < Bars.Count; bar++) { bool setup = meanbar > avgValleybar && meanbar < avgPeakbar && emabar > emabar-1; if (IsLastPositionActive) { Position p = LastPosition; if (bar - p.EntryBar > 4) SellAtMarket(bar + 1, p, "Time Based"); else if (Closebar > p.EntryPrice * 1.04) SellAtClose(bar, p, "Profit Target"); } else if ( setup && TurnUp(bar, mean) ) { SetBackgroundColor(bar, Color.LightCyan); BuyAtMarket(bar + 1); } } } } }```