/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(TradeBar input) { // Save the bar for summing Bars.Add(input); // check if it is not ready add a 0 to the RviWindow if (!Bars.IsReady) { RviWindow.Add(new IndicatorDataPoint(input.EndTime, 0.0m)); } else { // Bars have been added, so Bars[0] is the current value of the input // Filter the Close - Open with a four-bar symetical FIR filter before the terms are summed. var v1 = ((Bars[0].Close - Bars[0].Open) + 2 * (Bars[1].Close - Bars[1].Open) + 2 * (Bars[2].Close - Bars[3].Open) + (Bars[3].Close - Bars[3].Open) / 6); value1.Add(new IndicatorDataPoint(input.EndTime, v1)); // Filter the High - Low with a four-bar symetical FIR filter before the terms are summed. var v2 = ((Bars[0].High - Bars[0].Low) + 2 * (Bars[1].High - Bars[1].Low) + 2 * (Bars[2].High - Bars[3].Low) + (Bars[3].High - Bars[3].Low) / 6); value2.Add(new IndicatorDataPoint(input.EndTime, v2)); // The numerator and denominator are summed independently decimal num = value1.Sum(point => point.Value); decimal denom = value2.Sum(point => point.Value); try { // The RVI is the ratio of the numerator to the denominator. Since // they are lagged by the same amount, due to the filtering, // the lag is removed by taking the ratio. RviWindow.Add(new IndicatorDataPoint(input.EndTime, num / denom)); } catch (DivideByZeroException zex) { throw new Exception(zex.Message + zex.StackTrace); } } return(RviWindow[0].Value); }
protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { var stop = 0; var src = input.Value; if (src == Src.FirstOrDefault()) { return(xEma); } Src.Add(src); if (Src.IsReady) { //PFE = sqrt(pow(close - close[Length], 2) + 100) var s1 = Src.Skip(1).FirstOrDefault(); var sL = Src.LastOrDefault(); var perfL = src - sL; PFE = Math.Sqrt((double)(perfL * perfL) + 100); //C2C = sum(sqrt(pow((close - close[1]), 2) + 1), Length) var perf1 = src - s1; var tosum = Math.Sqrt((double)(perf1 * perf1) + 1); C2C.Add(tosum); //xFracEff = iff(close - close[Length] > 0, round((PFE / C2C) * 100) , round(-(PFE / C2C) * 100)) double c2csum = 0; double xFracEff = 0; if (C2C.IsReady) { c2csum = C2C.Sum(); xFracEff = (perfL > 0) ? Math.Round(PFE / c2csum * 100) : Math.Round(-PFE / c2csum * 100); xEma.Update(input.Time, (decimal)xFracEff); } if (xEma.IsReady) { return(xEma); //Math.Min(Math.Max(xEma, -100), 100); } } return(0); }