//populate public override void Populate() { TimeSeries ds = Parameters[0].AsTimeSeries; Int32 period1 = Parameters[1].AsInt; Int32 period2 = Parameters[2].AsInt; Int32 m = Parameters[3].AsInt; Int32 n = Parameters[4].AsInt; Int32 c = Parameters[5].AsInt; Boolean useRMSNoise = Parameters[6].AsBoolean; DateTimes = ds.DateTimes; var period = new List <int> { period1, period2, m, n, c }.Max(); if (period <= 0 || ds.Count == 0) { return; } //Assign first bar that contains indicator data if (n == 0) { n = 1; } n = Math.Abs(n); var FirstValidValue = n; if (FirstValidValue > ds.Count) { FirstValidValue = ds.Count; } if (ds.Count < n || ds == null) { return; } /* CPC and CPCTrend*/ var lpf1 = new EMA(ds, period1); var lpf2 = new EMA(ds, period2); var hCPC = new TimeSeries(DateTimes); var hTrend = new TimeSeries(DateTimes); double expnt = 2d / (1 + m); double cumSum = 0d; int xBar = 0; var mom = new Momentum(ds, 1); hCPC[0] = hTrend[0] = 0d; for (int bar = 0; bar < ds.Count; bar++) { hTrend[bar] = 0d; } for (int bar = 1; bar < ds.Count; bar++) { if (CrossOver(bar, lpf1, lpf2) || CrossUnder(bar, lpf1, lpf2)) { cumSum = 0d; xBar = bar; } else { cumSum += mom[bar]; } hCPC[bar] = cumSum; /* Calculate the Trend with a piecewise EMA */ if (bar - xBar > 0) { double diff = expnt * (hCPC[bar] - hTrend[bar - 1]); hTrend[bar] = hTrend[bar - 1] + diff; } } /* Trend Quality */ TimeSeries hDT = hCPC - hTrend; TimeSeries hNoise; if (useRMSNoise) { var hDTms = new SMA(hDT * hDT, n); hNoise = new TimeSeries(DateTimes); for (int bar = 0; bar < ds.Count; bar++) { hNoise[bar] = Math.Sqrt(hDTms[bar]); } } else { hNoise = new FastSMA(hDT.Abs(), n); } hNoise *= c; var hQ = hTrend / hNoise; for (int bar = 0; bar < ds.Count; bar++) { Values[bar] = hQ[bar]; } }