/// <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(IBaseDataBar input) { Minimum.Update(input.Time, input.Low); Maximum.Update(input.Time, input.High); if (!this.IsReady) { return(0); } var range = (Maximum.Current.Value - Minimum.Current.Value); return(range == 0 ? 0 : -100m * (Maximum.Current.Value - input.Close) / range); }
protected override decimal ComputeNextValue(TradeBar input) { _lowest.Update(new IndicatorDataPoint(input.EndTime, input.Close)); if (_lowest.IsReady) { Current = new IndicatorDataPoint(input.EndTime, ((_lowest.Current.Value - input.Close) / _lowest.Current.Value) * 100); } else { Current = new IndicatorDataPoint(input.EndTime, _lowest.Current.Value); //Current = new IndicatorDataPoint(input.EndTime,((_lowest.Current.Value - input.Close) / _lowest.Current.Value) * 100); } return(Current.Value); }
/// <summary> /// Computes the next value in the transform. /// value1 is a function used to normalize price withing the last _period day range. /// value1 is centered on its midpoint and then doubled so that value1 wil swing between -1 and +1. /// value1 is also smoothed with an exponential moving average whose alpha is 0.33. /// /// Since the smoothing may allow value1 to exceed the _period day price range, limits are introduced to /// preclude the transform from blowing up by having an input larger than unity. /// </summary> /// <param name="window">The IReadOnlyWindow of Indicator Data Points for the history of this indicator</param> /// <param name="input">IndicatorDataPoint - the time and value of the next price</param> /// <returns></returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { _maxHigh.Update(input); _minLow.Update(input); decimal fishx = 0; if (IsReady) { // get some local variables var price = input.Value; var minL = _minLow.Current.Value; var maxH = _maxHigh.Current.Value; if (price == 0) { Current = new IndicatorDataPoint(input.EndTime, 0); } else { // get the value1 from the last time this function was called var v1 = value1[0].Value; try { // compute the EMA of the price and the last value1 value1.Add(new IndicatorDataPoint(input.Time, .33m * 2m * ((price - minL) / (maxH - minL) - .5m) + .67m * v1)); } catch (Exception ex) { throw new Exception(ex.Message + ex.StackTrace); } try { // limit the new value1 so that it falls within positive or negative unity if (value1[0].Value > .9999m) { value1[0].Value = .9999m; } if (value1[0].Value < -.9999m) { value1[0].Value = -.9999m; } var current = Current; // calcuate the Fisher transform according the the formula above and from Ehlers // Math.Log takes and produces doubles, so the result is converted back to Decimal // The calculation uses the Current.Value from the last time the function was called, // so an intermediate variable is introduced so that it can be used in the // calculation before the result is assigned to the Current.Value after the calculation is made. fishx = Convert.ToDecimal(.5 * Math.Log((1.0 + (double)value1[0].Value) / (1.0 - (double)value1[0].Value))); } catch (Exception ex) { throw new Exception(ex.Message + ex.StackTrace); } } } return(fishx); }
/// <summary> /// AroonDown = 100 * (period - {periods since min})/period /// </summary> /// <param name="downPeriod">The AroonDown period</param> /// <param name="min">A Minimum indicator used to compute periods since min</param> /// <param name="input">The next input data</param> /// <returns>The AroonDown value</returns> private static decimal ComputeAroonDown(int downPeriod, Minimum min, IndicatorDataPoint input) { min.Update(input); return(100m * (downPeriod - min.PeriodsSinceMinimum) / downPeriod); }