protected override decimal ComputeNextValue(IndicatorDataPoint input) { double ifish = 0d; double normalized; mean.Update(input); sd.Update(input); if (mean.IsReady && sd.IsReady && sd != 0) { normalized = (double)(4 * (input - mean) / sd); ifish = (Math.Exp(2 * normalized) - 1) / (Math.Exp(2 * normalized) + 1); } return((decimal)ifish); }
/// <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(IndicatorDataPoint input) { var fastReady = Fast.Update(input); var slowReady = Slow.Update(input); var macd = Fast.Current.Value - Slow.Current.Value; if (fastReady && slowReady) { if (Signal.Update(input.Time, macd)) { Histogram.Update(input.Time, macd - Signal.Current.Value); } } return(macd); }
/// <summary> /// Configures the event handlers for Left.Updated and Right.Updated to update this instance when /// they both have new data. /// </summary> private void ConfigureEventHandlers() { // if either of these are constants then there's no reason bool leftIsConstant = Left.GetType().IsSubclassOfGeneric(typeof(ConstantIndicator <>)); bool rightIsConstant = Right.GetType().IsSubclassOfGeneric(typeof(ConstantIndicator <>)); // wire up the Updated events such that when we get a new piece of data from both left and right // we'll call update on this indicator. It's important to note that the CompositeIndicator only uses // the timestamp that gets passed into the Update function, his compuation is soley a function // of the left and right indicator via '_composer' IndicatorDataPoint newLeftData = null; IndicatorDataPoint newRightData = null; Left.Updated += (sender, updated) => { newLeftData = updated; // if we have left and right data (or if right is a constant) then we need to update if (newRightData != null || rightIsConstant) { Update(new T { Time = MaxTime(updated) }); // reset these to null after each update newLeftData = null; newRightData = null; } }; Right.Updated += (sender, updated) => { newRightData = updated; // if we have left and right data (or if left is a constant) then we need to update if (newLeftData != null || leftIsConstant) { Update(new T { Time = MaxTime(updated) }); // reset these to null after each update newLeftData = null; newRightData = null; } }; }
/// <summary> /// Updates the state of this indicator with the given value and returns true /// if this indicator is ready, false otherwise /// </summary> /// <param name="input">The value to use to update this indicator</param> /// <returns>True if this indicator is ready, false otherwise</returns> public bool Update(T input) { if (_previousInput != null && input.Time < _previousInput.Time) { // if we receive a time in the past, throw throw new ArgumentException("This is a forward only indicator."); } if (!ReferenceEquals(input, _previousInput)) { // compute a new value and update our previous time Samples++; _previousInput = input; var nextValue = ComputeNextValue(input); Current = new IndicatorDataPoint(input.Time, nextValue); } return(IsReady); }
/// <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(IndicatorDataPoint input) { // Update internal indicator, automatically updates _maximum and _minimum _MACD.Update(input); // Update our Stochastics K, automatically updates our Stochastics D variable which is a smoothed version of K var MACD_K = new IndicatorDataPoint(input.Time, ComputeStoch(_MACD.Current.Value, _maximum.Current.Value, _minimum.Current.Value)); _K.Update(MACD_K); // With our Stochastic D values calculate PF var PF = new IndicatorDataPoint(input.Time, ComputeStoch(_D.Current.Value, _maximumD.Current.Value, _minimumD.Current.Value)); _PF.Update(PF); return(_PFF.Current.Value); }
/// <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(IndicatorDataPoint input) { // Until the windows is ready, the indicator returns the input value. decimal output = input; seriesQ.Enqueue((double)input.Value); if (IsReady) { seriesQ.Dequeue(); var series = seriesQ.ToArray(); // Fit OLS Tuple <double, double> ols = Fit.Line(x: t, y: series); var alfa = (decimal)ols.Item1; var beta = (decimal)ols.Item2; // Make the projection. output = alfa + beta * (_period); } return(output); }
/// <summary> /// Updates the state of this indicator with the given value and returns true /// if this indicator is ready, false otherwise /// </summary> /// <param name="input">The value to use to update this indicator</param> /// <returns>True if this indicator is ready, false otherwise</returns> public bool Update(T input) { if (_previousInput != null && input.Time < _previousInput.Time) { // if we receive a time in the past, throw throw new ArgumentException("This is a forward only indicator: Input: " + input.Time.ToString("u") + " Previous: " + _previousInput.Time.ToString("u")); } if (!ReferenceEquals(input, _previousInput)) { // compute a new value and update our previous time Samples++; _previousInput = input; var nextValue = ComputeNextValue(input); Current = new IndicatorDataPoint(input.Time, nextValue); // let others know we've produced a new data point OnUpdated(Current); } return(IsReady); }
/// <summary> /// Computes the next value for this indicator from the given state. /// </summary> /// <param name="input">The input value to this indicator on this time step</param> /// <returns>A a value for this indicator</returns> protected override decimal ComputeNextValue(IndicatorDataPoint input) { _rollingData.Add(input.Value); if (_rollingData.Count < 3) { return(0m); } var previousPoint = _rollingData[1]; var previousPoint2 = _rollingData[2]; var logPoint = 0.0; if (previousPoint2 != 0) { logPoint = Math.Log((double)(previousPoint / previousPoint2)); } _standardDeviation.Update(input.Time, (decimal)logPoint); if (!_rollingData.IsReady) { return(0m); } if (!_standardDeviation.IsReady) { return(0m); } var m = _standardDeviation.Current.Value * previousPoint; if (m == 0) { return(0); } var spikeValue = (input.Value - previousPoint) / m; return(spikeValue); }
/// <summary> /// Forecasts the series of the fitted model one point ahead. /// </summary> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IndicatorDataPoint input) { _rollingData.Add((double)input.Value); if (_rollingData.IsReady) { var arrayData = _rollingData.ToArray(); arrayData = _diffOrder > 0 ? DifferenceSeries(_diffOrder, arrayData, out _diffHeads) : arrayData; TwoStepFit(arrayData); double summants = 0; if (_arOrder > 0) { for (var i = 0; i < _arOrder; i++) // AR Parameters { summants += ArParameters[i] * arrayData[i]; } } if (_maOrder > 0) { for (var i = 0; i < _maOrder; i++) // MA Parameters { summants += MaParameters[i] * _residuals[_maOrder + i + 1]; } } summants += Intercept; // By default equals 0 if (_diffOrder > 0) { var dataCast = arrayData.ToList(); dataCast.Insert(0, summants); // Prepends summants = InverseDifferencedSeries(dataCast.ToArray(), _diffHeads).First(); // Returns disintegrated series } return((decimal)summants); } return(0m); }
/// <summary> /// Updates the state of this indicator with the given value and returns true /// if this indicator is ready, false otherwise /// </summary> /// <param name="input">The value to use to update this indicator</param> /// <returns>True if this indicator is ready, false otherwise</returns> public bool Update(T input) { if (_previousInput != null && input.Time < _previousInput.Time) { // if we receive a time in the past, throw throw new ArgumentException(string.Format("This is a forward only indicator: {0} Input: {1} Previous: {2}", Name, input.Time.ToString("u"), _previousInput.Time.ToString("u"))); } if (!ReferenceEquals(input, _previousInput)) { // compute a new value and update our previous time Samples++; _previousInput = input; var nextResult = ValidateAndComputeNextValue(input); if (nextResult.Status == IndicatorStatus.Success) { Current = new IndicatorDataPoint(input.Time, nextResult.Value); // let others know we've produced a new data point OnUpdated(Current); } } return(IsReady); }
/// <summary> /// Initializes a new instance of the Indicator class using the specified name. /// </summary> /// <param name="name">The name of this indicator</param> protected IndicatorBase(string name) { Name = name; Current = new IndicatorDataPoint(DateTime.MinValue, 0m); }
/// <summary> /// Resets this indicator to its initial state /// </summary> public virtual void Reset() { Samples = 0; Current = new IndicatorDataPoint(DateTime.MinValue, default(decimal)); }
/// <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); }
/// <summary> /// AroonUp = 100 * (period - {periods since max})/period /// </summary> /// <param name="upPeriod">The AroonUp period</param> /// <param name="max">A Maximum indicator used to compute periods since max</param> /// <param name="input">The next input data</param> /// <returns>The AroonUp value</returns> private static decimal ComputeAroonUp(int upPeriod, Maximum max, IndicatorDataPoint input) { max.Update(input); return(100m * (upPeriod - max.PeriodsSinceMaximum) / upPeriod); }
private DateTime MaxTime(IndicatorDataPoint updated) { return(new DateTime(Math.Max(updated.Time.Ticks, Math.Max(Right.Current.Time.Ticks, Left.Current.Time.Ticks)))); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <remarks> /// Since this class overrides <see cref="ValidateAndComputeNextValue"/>, this method is a no-op /// </remarks> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IndicatorDataPoint input) { // this should never actually be invoked return(_composer.Invoke(Left, Right).Value); }
/// <summary> /// Computes the next value of this indicator from the given state /// and returns an instance of the <see cref="IndicatorResult"/> class /// </summary> /// <param name="input">The input given to the indicator</param> /// <returns>An IndicatorResult object including the status of the indicator</returns> protected override IndicatorResult ValidateAndComputeNextValue(IndicatorDataPoint input) { return(_composer.Invoke(Left, Right)); }
/// <summary> /// Event invocator for the Updated event /// </summary> /// <param name="consolidated">This is the new piece of data produced by this indicator</param> protected virtual void OnUpdated(IndicatorDataPoint consolidated) { Updated?.Invoke(this, consolidated); }
/// <summary> /// Initializes a new instance of the Indicator class. /// </summary> protected IndicatorBase() { Current = new IndicatorDataPoint(DateTime.MinValue, 0m); }
/// <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(IndicatorDataPoint input) { _previousRsi = _currentRsi; _currentRsi = _rsi; return(_currentRsi); }
/// <summary> /// Resets this indicator to its initial state /// </summary> public virtual void Reset() { Samples = 0; _previousInput.Clear(); Current = new IndicatorDataPoint(DateTime.MinValue, default(decimal)); }
/// <summary> /// Computes the next value of the following sub-indicators from the given state: /// StandardDeviation, MiddleBand, UpperBand, LowerBand /// </summary> /// <param name="input">The input given to the indicator</param> /// <returns>The input is returned unmodified.</returns> protected override decimal ComputeNextValue(IndicatorDataPoint input) { StandardDeviation.Update(input); MiddleBand.Update(input); return(input); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="input">The input given to the indicator</param> /// <param name="window">The window for the input history</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { return((decimal)Math.Sqrt((double)base.ComputeNextValue(window, input))); }