public override void ApplyTo(StockSerie stockSerie) { using (MethodLogger ml = new MethodLogger(this)) { List<StockDailyValue> dailyValues = stockSerie.GenerateHeikinAshiBarFromDaily(stockSerie.Values.ToList()); FloatSerie upVolume = new FloatSerie(stockSerie.Count); FloatSerie downVolume = new FloatSerie(stockSerie.Count); int i = -1; foreach (StockDailyValue dailyValue in dailyValues) { i++; float R = dailyValue.HIGH - dailyValue.LOW; // Bar range float R2 = Math.Abs(dailyValue.CLOSE - dailyValue.OPEN); // Body range if (R == 0 || R2 == 0) { upVolume[i] = downVolume[i] = dailyValue.VOLUME / 2L; continue; } float R1 = dailyValue.HIGH - Math.Max(dailyValue.CLOSE, dailyValue.OPEN); // Higher shade range float R3 = Math.Min(dailyValue.CLOSE, dailyValue.OPEN) - dailyValue.LOW; // Lower shade range float V = dailyValue.VOLUME; float V1 = V * (R1 / R); float V2 = V * (R2 / R); float V3 = V * (R3 / R); if (dailyValue.CLOSE > dailyValue.OPEN) // UpBar { upVolume[i] = V2 + (V1 + V3) / 2.0f; downVolume[i] = V - upVolume[i]; } else // DownBar { downVolume[i] = V2 + (V1 + V3) / 2.0f; upVolume[i] = V - downVolume[i]; } //V = V(R1/R) + V(R2/R) + V(R3/R); } //FloatSerie upVolume = stockSerie.GetSerie(StockDataType.UPVOLUME).Sqrt(); //FloatSerie downVolume = stockSerie.GetSerie(StockDataType.DOWNVOLUME).Sqrt(); FloatSerie cumulVolume = (upVolume - downVolume).Cumul(); FloatSerie diffVolume = (cumulVolume - cumulVolume.CalculateEMA((int)this.parameters[0])).CalculateEMA((int)this.parameters[1]); FloatSerie fastSerie = diffVolume; FloatSerie fastMom = fastSerie; this.series[0] = fastMom; this.Series[0].Name = this.Name; FloatSerie signalSerie = fastMom.CalculateEMA(((int)this.parameters[2])); this.series[1] = signalSerie; this.Series[1].Name = this.SerieNames[1]; if (this.series[0] != null && this.Series[0].Count > 0) { this.CreateEventSeries(stockSerie.Count); FloatSerie upExLimit = new FloatSerie(stockSerie.Count, this.SerieNames[1]); FloatSerie downExLimit = new FloatSerie(stockSerie.Count, this.SerieNames[2]); FloatSerie highSerie = stockSerie.GetSerie(StockDataType.HIGH); FloatSerie lowSerie = stockSerie.GetSerie(StockDataType.LOW); FloatSerie indicatorToDecorate = this.Series[0]; float exhaustionSellLimit = indicatorToDecorate[0]; float exhaustionBuyLimit = indicatorToDecorate[0]; float exhaustionBuyPrice = highSerie[0]; float exhaustionSellPrice = lowSerie[0]; float exFadeOut = (100.0f - (float)this.parameters[3]) / 100.0f; float previousValue = indicatorToDecorate[0]; float currentValue; for (i = 1; i < indicatorToDecorate.Count - 1; i++) { currentValue = indicatorToDecorate[i]; if (currentValue < previousValue) { if (indicatorToDecorate.IsBottom(i)) { if (currentValue <= exhaustionSellLimit) { // This is an exhaustion selling exhaustionSellPrice = lowSerie[i]; exhaustionSellLimit = currentValue; } else { exhaustionSellLimit *= exFadeOut; } exhaustionBuyLimit *= exFadeOut; } else { // trail exhaustion limit down exhaustionSellLimit = Math.Min(currentValue, exhaustionSellLimit); exhaustionBuyLimit *= exFadeOut; } } else if (currentValue > previousValue) { if (indicatorToDecorate.IsTop(i)) { if (currentValue >= exhaustionBuyLimit) { // This is an exhaustion selling exhaustionBuyPrice = highSerie[i]; exhaustionBuyLimit = currentValue; } else { exhaustionSellLimit *= exFadeOut; } exhaustionBuyLimit *= exFadeOut; } else { // trail exhaustion limit up exhaustionBuyLimit = Math.Max(currentValue, exhaustionBuyLimit); exhaustionSellLimit *= exFadeOut; } } else { exhaustionSellLimit *= exFadeOut; exhaustionBuyLimit *= exFadeOut; } previousValue = currentValue; upExLimit[i] = exhaustionBuyLimit; downExLimit[i] = exhaustionSellLimit; } upExLimit[indicatorToDecorate.Count - 1] = exhaustionBuyLimit; downExLimit[indicatorToDecorate.Count - 1] = exhaustionSellLimit; this.series[2] = upExLimit; this.series[3] = downExLimit; //for ( i = 5; i < indicatorToDecorate.Count - 1; i++) //{ // this.eventSeries[0][i] = fastMom[i - 1] == upExLimit[i - 1] && fastMom[i] < fastMom[i - 1]; // this.eventSeries[1][i] = fastMom[i - 1] == downExLimit[i - 1] && fastMom[i] > fastMom[i - 1]; //} } else { for (i = 0; i < this.SeriesCount; i++) { this.Series[i] = new FloatSerie(0, this.SerieNames[i]); } } for (i = 0; i < stockSerie.Count; i++) { this.eventSeries[0][i] = fastMom[i] >= signalSerie[i]; this.eventSeries[1][i] = fastMom[i] < signalSerie[i]; } } }