/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(long time, DoubleArray input) { _trueRange.Update(time, input); if (Samples == 1) { _previousInput = input.Clone(); return(50.0d); } var buyingPressure = new DoubleArrayScalar(input[CloseIdx] - Math.Min(input[LowIdx], _previousInput.Close)); _sumBuyingPressure1.Update(time, buyingPressure); _sumBuyingPressure2.Update(time, buyingPressure); _sumBuyingPressure3.Update(time, buyingPressure); _sumTrueRange1.Update(time, _trueRange.Current); _sumTrueRange2.Update(time, _trueRange.Current); _sumTrueRange3.Update(time, _trueRange.Current); _previousInput = input; if (!IsReady) { return(50.0d); } var average1 = _sumBuyingPressure1 / _sumTrueRange1; var average2 = _sumBuyingPressure2 / _sumTrueRange2; var average3 = _sumBuyingPressure3 / _sumTrueRange3; return(100.0d * (4 * average1 + 2 * average2 + average3) / 7); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="time"></param> /// <param name="input">The trade bar input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(long time, DoubleArray input) { // On first iteration we can’t produce an SAR value so we save the current bar and return zero if (Samples == 1) { _previousBar = input.Clone(); // return a value that's close to where we will be, returning 0 doesn't make sense return(input[CloseIdx]); } // On second iteration we initiate the position the extreme point and the SAR if (Samples == 2) { Init(input); _previousBar = input; return(_sar); } if (_isLong) { HandleLongPosition(input); } else { HandleShortPosition(input); } _previousBar = input; return(_outputSar); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(long time, DoubleArray input) { _trueRange.Update(time, input); _directionalMovementPlus.Update(time, input); _directionalMovementMinus.Update(time, input); _smoothedTrueRange.Update(time, Current); _smoothedDirectionalMovementPlus.Update(time, Current); _smoothedDirectionalMovementMinus.Update(time, Current); _previousInput = input.Clone(); PositiveDirectionalIndex.Update(time, Current); NegativeDirectionalIndex.Update(time, Current); var diff = Math.Abs(PositiveDirectionalIndex.Current.Value - NegativeDirectionalIndex); var sum = PositiveDirectionalIndex + NegativeDirectionalIndex; if (sum == 0) { return((DoubleArray)50d); } _averageDirectionalIndex.Update(time, 100d * diff / sum); return(_averageDirectionalIndex); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator, which by convention is the mean value of the upper band and lower band.</returns> protected override DoubleArray Forward(long time, DoubleArray input) { if (_previousInput != null) { UpperBand.Update(_previousTime, _previousInput.High); LowerBand.Update(_previousTime, _previousInput.Low); } _previousInput = input.Clone(); _previousTime = time; return((UpperBand + LowerBand) / 2); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(long time, DoubleArray input) { if (_filter(input)) { _previousInput = input.Clone(); return(input); } if (_previousInput != null) { return(_previousInput.Clone()); } _previousInput = Constants.Empty; return(_previousInput.Clone()); }
/// <summary> /// Updates the state of this indicator with the given value and returns true /// if this indicator is ready, false otherwise /// </summary> /// <param name="time"></param> /// <param name="input">The value to use to update this indicator</param> /// <returns>True if this indicator is ready, false otherwise</returns> public override void Update(long time, DoubleArray input) { #if DEBUG if (this.InputProperties > input.Properties) { throw new ArgumentException($"Unable to update with given input because atleast {InputProperties} properties required but got input with {input.Properties} properties."); } #endif double volume, averagePrice; if (!TryGetVolumeAndAveragePrice(input, out volume, out averagePrice)) { return; } // reset vwap on daily boundaries var date = time.ToDateTime().Date; if (_lastDate != date) { _sumOfVolume = Constants.Zero; _sumOfPriceTimesVolume = Constants.Zero; _lastDate = date; } // running totals for Σ PiVi / Σ Vi _sumOfVolume += volume; _sumOfPriceTimesVolume += averagePrice * volume; CurrentTime = time; Samples++; if (_sumOfVolume == Constants.Zero) { // if we have no trade volume then use the current price as VWAP Current = input.Clone(); OnUpdated(time, Current); return; } Current = _sumOfPriceTimesVolume / _sumOfVolume; OnUpdated(time, Current); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(long time, DoubleArray input) { return(input.Clone()); }