Пример #1
0
 /// <summary>Initializes a new instance of the SimpleMovingAverage class with the specified name and period from the left indicator
 /// </summary>
 /// <param name="left">The SimpleMovingAverage indicator will be created using the data from left</param>
 /// <param name="period">The period of the SMA</param>
 /// <param name="waitForFirstToReady">True to only send updates to the second if first.IsReady returns true, false to always send updates to second</param>
 /// <returns>The reference to the SimpleMovingAverage indicator to allow for method chaining</returns>
 public static SimpleMovingAverage SMA <T>(this IndicatorBase <T> left, int period, bool waitForFirstToReady = true)
     where T : IBaseData
 {
     return(new SimpleMovingAverage($"SMA{period}_Of_{left.Name}", period).Of(left, waitForFirstToReady));
 }
Пример #2
0
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the product of the left to the right
 /// </summary>
 /// <remarks>
 /// value = left*right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <param name="name">The name of this indicator</param>
 /// <returns>The product of the left to the right indicators</returns>
 public static CompositeIndicator <T> Times <T>(this IndicatorBase <T> left, IndicatorBase <T> right, string name)
     where T : IBaseData
 {
     return(new CompositeIndicator <T>(name, left, right, (l, r) => l.Current.Value * r.Current.Value));
 }
Пример #3
0
 /// <summary>Creates a new Minimum indicator with the specified period from the left indicator
 /// </summary>
 /// <param name="left">The Minimum indicator will be created using the data from left</param>
 /// <param name="period">The period of the Minimum indicator</param>
 /// <param name="waitForFirstToReady">True to only send updates to the second if left.IsReady returns true, false to always send updates</param>
 /// <returns>A reference to the Minimum indicator to allow for method chaining</returns>
 public static Minimum MIN <T>(this IndicatorBase <T> left, int period, bool waitForFirstToReady = true)
     where T : IBaseData
 {
     return(new Minimum($"MIN{period}_Of_{left.Name}", period).Of(left, waitForFirstToReady));
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="AverageDirectionalIndex"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="period">The period.</param>
        public AverageDirectionalIndex(string name, int period)
            : base(name)
        {
            _period = period;

            _trueRange = new FunctionalIndicator <IBaseDataBar>(name + "_TrueRange",
                                                                ComputeTrueRange,
                                                                isReady => _previousInput != null
                                                                );

            _directionalMovementPlus = new FunctionalIndicator <IBaseDataBar>(name + "_PositiveDirectionalMovement",
                                                                              ComputePositiveDirectionalMovement,
                                                                              isReady => _previousInput != null
                                                                              );

            _directionalMovementMinus = new FunctionalIndicator <IBaseDataBar>(name + "_NegativeDirectionalMovement",
                                                                               ComputeNegativeDirectionalMovement,
                                                                               isReady => _previousInput != null
                                                                               );

            PositiveDirectionalIndex = new FunctionalIndicator <IndicatorDataPoint>(name + "_PositiveDirectionalIndex",
                                                                                    input =>
            {
                // Computes the Plus Directional Indicator(+DI period).
                if (_smoothedTrueRange != 0 && _smoothedDirectionalMovementPlus.IsReady)
                {
                    return(100m * _smoothedDirectionalMovementPlus / _smoothedTrueRange);
                }
                return(0m);
            },
                                                                                    positiveDirectionalIndex => _smoothedDirectionalMovementPlus.IsReady,
                                                                                    () =>
            {
                _directionalMovementPlus.Reset();
                _trueRange.Reset();
            }
                                                                                    );

            NegativeDirectionalIndex = new FunctionalIndicator <IndicatorDataPoint>(name + "_NegativeDirectionalIndex",
                                                                                    input =>
            {
                // Computes the Minus Directional Indicator(-DI period).
                if (_smoothedTrueRange != 0 && _smoothedDirectionalMovementMinus.IsReady)
                {
                    return(100m * _smoothedDirectionalMovementMinus / _smoothedTrueRange);
                }
                return(0m);
            },
                                                                                    negativeDirectionalIndex => _smoothedDirectionalMovementMinus.IsReady,
                                                                                    () =>
            {
                _directionalMovementMinus.Reset();
                _trueRange.Reset();
            }
                                                                                    );

            _smoothedTrueRange = new FunctionalIndicator <IndicatorDataPoint>(name + "_SmoothedTrueRange",
                                                                              input =>
            {
                // Computes the Smoothed True Range value.
                var value = Samples > _period + 1 ? _smoothedTrueRange / _period : 0m;
                return(_smoothedTrueRange + _trueRange - value);
            },
                                                                              isReady => Samples > period
                                                                              );

            _smoothedDirectionalMovementPlus = new FunctionalIndicator <IndicatorDataPoint>(name + "_SmoothedDirectionalMovementPlus",
                                                                                            input =>
            {
                // Computes the Smoothed Directional Movement Plus value.
                var value = Samples > _period + 1 ? _smoothedDirectionalMovementPlus / _period : 0m;
                return(_smoothedDirectionalMovementPlus + _directionalMovementPlus - value);
            },
                                                                                            isReady => Samples > period
                                                                                            );

            _smoothedDirectionalMovementMinus = new FunctionalIndicator <IndicatorDataPoint>(name + "_SmoothedDirectionalMovementMinus",
                                                                                             input =>
            {
                // Computes the Smoothed Directional Movement Minus value.
                var value = Samples > _period + 1 ? _smoothedDirectionalMovementMinus / _period : 0m;
                return(_smoothedDirectionalMovementMinus + _directionalMovementMinus - value);
            },
                                                                                             isReady => Samples > period
                                                                                             );

            _averageDirectionalIndex = new WilderMovingAverage(period);
        }
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the difference of the left and right
 /// </summary>
 /// <remarks>
 /// value = left - right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <param name="name">The name of this indicator</param>
 /// <returns>The difference of the left and right indicators</returns>
 public static CompositeIndicator <T> Minus <T>(this IndicatorBase <T> left, IndicatorBase <T> right, string name)
     where T : IBaseData
 {
     return(new CompositeIndicator <T>(name, left, right, (l, r) => l - r));
 }
Пример #6
0
 /// <summary>
 /// Initializes a new instance of the MeanAbsoluteDeviation class with the specified period.
 ///
 /// Evaluates the mean absolute deviation of samples in the look-back period.
 /// </summary>
 /// <param name="name">The name of this indicator</param>
 /// <param name="period">The sample size of the mean absolute deviation</param>
 public MeanAbsoluteDeviation(string name, int period)
     : base(name, period)
 {
     Mean = new SimpleMovingAverage($"{name}_Mean", period);
 }
Пример #7
0
 /// <summary>
 /// Creates a new SequentialIndicator that will pipe the output of the first into the second
 /// </summary>
 /// <param name="first">The first indicator to receive data</param>
 /// <param name="second">The indicator to receive the first's output data</param>
 public SequentialIndicator(IndicatorBase <TFirst> first, IndicatorBase <IndicatorDataPoint> second)
     : base(string.Format("SEQUENTIAL({0}->{1})", first.Name, second.Name))
 {
     First  = first;
     Second = second;
 }
Пример #8
0
 /// <summary>
 /// Updates the state of this indicator with the given value and returns true
 /// if this indicator is ready, false otherwise
 /// </summary>
 /// <param name="indicator">The indicator to be updated</param>
 /// <param name="time">The time associated with the value</param>
 /// <param name="value">The value to use to update this indicator</param>
 /// <returns>True if this indicator is ready, false otherwise</returns>
 public static void Update(this IndicatorBase <IndicatorDataPoint> indicator, DateTime time, decimal value)
 {
     indicator.Update(new IndicatorDataPoint(time, value));
 }
Пример #9
0
 /// <summary>
 /// Creates a new SequentialIndicator such that data from 'first' is piped into 'second'
 /// </summary>
 /// <param name="second">The indicator that wraps the first</param>
 /// <param name="first">The indicator to be wrapped</param>
 /// <param name="name">The name of the new indicator</param>
 /// <returns>A new SequentialIndicator that pipes data from first to second</returns>
 public static SequentialIndicator <T> Of <T>(this IndicatorBase <IndicatorDataPoint> second, IndicatorBase <T> first, string name)
     where T : BaseData
 {
     return(new SequentialIndicator <T>(first, second));
 }
Пример #10
0
        /// <summary>
        /// Creates a new CompositeIndicator such that the result will be the product of the left and the constant
        /// </summary>
        /// <remarks>
        /// value = left*constant
        /// </remarks>
        /// <param name="left">The left indicator</param>
        /// <param name="constant">The constant value to multiple by</param>
        /// <returns>The product of the left to the right indicators</returns>
        public static CompositeIndicator <IndicatorDataPoint> Times(this IndicatorBase <IndicatorDataPoint> left, decimal constant)
        {
            var constantIndicator = new ConstantIndicator <IndicatorDataPoint>(constant.ToString(CultureInfo.InvariantCulture), constant);

            return(left.Times(constantIndicator));
        }
Пример #11
0
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the product of the left to the right
 /// </summary>
 /// <remarks>
 /// value = left*right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <returns>The product of the left to the right indicators</returns>
 public static CompositeIndicator <IndicatorDataPoint> Times(this IndicatorBase <IndicatorDataPoint> left, IndicatorBase <IndicatorDataPoint> right)
 {
     return(new CompositeIndicator <IndicatorDataPoint>(left, right, (l, r) => l * r));
 }
Пример #12
0
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the ratio of the left to the right
 /// </summary>
 /// <remarks>
 /// value = left/right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <param name="name">The name of this indicator</param>
 /// <returns>The ratio of the left to the right indicator</returns>
 public static CompositeIndicator <IndicatorDataPoint> Over(this IndicatorBase <IndicatorDataPoint> left, IndicatorBase <IndicatorDataPoint> right, string name)
 {
     return(new CompositeIndicator <IndicatorDataPoint>(name, left, right, (l, r) => r == 0m ? new IndicatorResult(0m, IndicatorStatus.MathError) : new IndicatorResult(l / r)));
 }
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the product of the left to the right
 /// </summary>
 /// <remarks>
 /// value = left*right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <returns>The product of the left to the right indicators</returns>
 public static CompositeIndicator <T> Times <T>(this IndicatorBase <T> left, IndicatorBase <T> right)
     where T : IBaseData
 {
     return(new CompositeIndicator <T>(left, right, (l, r) => l * r));
 }
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the ratio of the left to the right
 /// </summary>
 /// <remarks>
 /// value = left/right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <returns>The ratio of the left to the right indicator</returns>
 public static CompositeIndicator <T> Over <T>(this IndicatorBase <T> left, IndicatorBase <T> right)
     where T : IBaseData
 {
     return(new CompositeIndicator <T>(left, right, (l, r) => r == 0m ? new IndicatorResult(0m, IndicatorStatus.MathError) : new IndicatorResult(l / r)));
 }
Пример #15
0
 /// <summary>
 /// Updates the state of this indicator with the given value and returns true
 /// if this indicator is ready, false otherwise
 /// </summary>
 /// <param name="indicator">The indicator to be updated</param>
 /// <param name="time">The time associated with the value</param>
 /// <param name="value">The value to use to update this indicator</param>
 /// <returns>True if this indicator is ready, false otherwise</returns>
 public static bool Update(this IndicatorBase <IndicatorDataPoint> indicator, DateTime time, decimal value)
 {
     return(indicator.Update(new IndicatorDataPoint(time, value)));
 }
Пример #16
0
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the sum of the left and right
 /// </summary>
 /// <remarks>
 /// value = left + right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <param name="name">The name of this indicator</param>
 /// <returns>The sum of the left and right indicators</returns>
 public static CompositeIndicator <IndicatorDataPoint> Plus(this IndicatorBase <IndicatorDataPoint> left, IndicatorBase <IndicatorDataPoint> right, string name)
 {
     return(new CompositeIndicator <IndicatorDataPoint>(name, left, right, (l, r) => l + r));
 }
Пример #17
0
        /// <summary>
        /// Creates a new CompositeIndicator such that the result will be average of a first indicator weighted by a second one
        /// </summary>
        /// <param name="value">Indicator that will be averaged</param>
        /// <param name="weight">Indicator that provides the average weights</param>
        /// <param name="period">Average period</param>
        /// <returns>Indicator that results of the average of first by weights given by second</returns>
        public static CompositeIndicator <IndicatorDataPoint> WeightedBy <T, TWeight>(this IndicatorBase <T> value, TWeight weight, int period)
            where T : IBaseData
            where TWeight : IndicatorBase <IndicatorDataPoint>
        {
            var x           = new WindowIdentity(period);
            var y           = new WindowIdentity(period);
            var numerator   = new Sum("Sum_xy", period);
            var denominator = new Sum("Sum_y", period);

            value.Updated += (sender, consolidated) =>
            {
                x.Update(consolidated);
                if (x.Samples == y.Samples)
                {
                    numerator.Update(consolidated.Time, consolidated.Value * y.Current.Value);
                }
            };

            weight.Updated += (sender, consolidated) =>
            {
                y.Update(consolidated);
                if (x.Samples == y.Samples)
                {
                    numerator.Update(consolidated.Time, consolidated.Value * x.Current.Value);
                }
                denominator.Update(consolidated);
            };

            return(numerator.Over(denominator));
        }
Пример #18
0
 /// <summary>
 /// Initializes a new instance of the MeanAbsoluteDeviation class with the specified period.
 ///
 /// Evaluates the mean absolute deviation of samples in the lookback period.
 /// </summary>
 /// <param name="name">The name of this indicator</param>
 /// <param name="period">The sample size of the mean absoluate deviation</param>
 public MeanAbsoluteDeviation(string name, int period)
     : base(name, period)
 {
     Mean = MovingAverageType.Simple.AsIndicator(string.Format("{0}_{1}", name, "Mean"), period);
 }
Пример #19
0
 /// <summary>
 /// Creates a new SequentialIndicator that will pipe the output of the first into the second
 /// </summary>
 /// <param name="name">The name of this indicator</param>
 /// <param name="first">The first indicator to receive data</param>
 /// <param name="second">The indicator to receive the first's output data</param>
 public SequentialIndicator(string name, IndicatorBase <TFirst> first, IndicatorBase <IndicatorDataPoint> second)
     : base(name)
 {
     First  = first;
     Second = second;
 }
Пример #20
0
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the difference of the left and right
 /// </summary>
 /// <remarks>
 /// value = left - right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <returns>The difference of the left and right indicators</returns>
 public static CompositeIndicator <T> Minus <T>(this IndicatorBase <T> left, IndicatorBase <T> right)
     where T : IBaseData
 {
     return(new CompositeIndicator <T>(left, right, (l, r) => l.Current.Value - r.Current.Value));
 }
Пример #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DonchianChannel"/> class.
 /// </summary>
 /// <param name="name">The name.</param>
 /// <param name="upperPeriod">The period for the upper channel.</param>
 /// <param name="lowerPeriod">The period for the lower channel</param>
 public DonchianChannel(string name, int upperPeriod, int lowerPeriod)
     : base(name)
 {
     UpperBand = new Maximum(name + "_UpperBand", upperPeriod);
     LowerBand = new Minimum(name + "_LowerBand", lowerPeriod);
 }
Пример #22
0
 /// <summary>
 /// Creates a new CompositeIndicator such that the result will be the ratio of the left to the right
 /// </summary>
 /// <remarks>
 /// value = left/right
 /// </remarks>
 /// <param name="left">The left indicator</param>
 /// <param name="right">The right indicator</param>
 /// <param name="name">The name of this indicator</param>
 /// <returns>The ratio of the left to the right indicator</returns>
 public static CompositeIndicator <T> Over <T>(this IndicatorBase <T> left, IndicatorBase <T> right, string name)
     where T : IBaseData
 {
     return(new CompositeIndicator <T>(name, left, right, (l, r) => r.Current.Value == 0m ? new IndicatorResult(0m, IndicatorStatus.MathError) : new IndicatorResult(l.Current.Value / r.Current.Value)));
 }
Пример #23
0
 /// <summary>
 /// Creates a new AverageTrueRange indicator using the specified period and moving average type
 /// </summary>
 /// <param name="name">The name of this indicator</param>
 /// <param name="period">The smoothing period used to smooth the true range values</param>
 /// <param name="movingAverageType">The type of smoothing used to smooth the true range values</param>
 public AverageTrueRange(string name, int period, MovingAverageType movingAverageType = MovingAverageType.Wilders)
     : base(name)
 {
     _smoother = movingAverageType.AsIndicator(string.Format("{0}_{1}", name, movingAverageType), period);
 }
Пример #24
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AverageDirectionalIndex"/> class.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="period">The period.</param>
        public AverageDirectionalIndex(string name, int period)
            : base(name)
        {
            _period = period;

            TrueRange = new FunctionalIndicator <TradeBar>(name + "_TrueRange",
                                                           currentBar =>
            {
                var value = ComputeTrueRange(currentBar);
                return(value);
            },
                                                           isReady => _previousInput != null
                                                           );

            DirectionalMovementPlus = new FunctionalIndicator <TradeBar>(name + "_PositiveDirectionalMovement",
                                                                         currentBar =>
            {
                var value = ComputePositiveDirectionalMovement(currentBar);
                return(value);
            },
                                                                         isReady => _previousInput != null
                                                                         );


            DirectionalMovementMinus = new FunctionalIndicator <TradeBar>(name + "_NegativeDirectionalMovement",
                                                                          currentBar =>
            {
                var value = ComputeNegativeDirectionalMovement(currentBar);
                return(value);
            },
                                                                          isReady => _previousInput != null
                                                                          );

            PositiveDirectionalIndex = new FunctionalIndicator <IndicatorDataPoint>(name + "_PositiveDirectionalIndex",
                                                                                    input => ComputePositiveDirectionalIndex(),
                                                                                    positiveDirectionalIndex => DirectionalMovementPlus.IsReady && TrueRange.IsReady,
                                                                                    () =>
            {
                DirectionalMovementPlus.Reset();
                TrueRange.Reset();
            }
                                                                                    );

            NegativeDirectionalIndex = new FunctionalIndicator <IndicatorDataPoint>(name + "_NegativeDirectionalIndex",
                                                                                    input => ComputeNegativeDirectionalIndex(),
                                                                                    negativeDirectionalIndex => DirectionalMovementMinus.IsReady && TrueRange.IsReady,
                                                                                    () =>
            {
                DirectionalMovementMinus.Reset();
                TrueRange.Reset();
            }
                                                                                    );

            SmoothedTrueRange = new FunctionalIndicator <IndicatorDataPoint>(name + "_SmoothedTrueRange",
                                                                             currentBar => ComputeSmoothedTrueRange(period),
                                                                             isReady => _previousInput != null
                                                                             );


            SmoothedDirectionalMovementPlus = new FunctionalIndicator <IndicatorDataPoint>(name + "_SmoothedDirectionalMovementPlus",
                                                                                           currentBar => ComputeSmoothedDirectionalMovementPlus(period),
                                                                                           isReady => _previousInput != null
                                                                                           );

            SmoothedDirectionalMovementMinus = new FunctionalIndicator <IndicatorDataPoint>(name + "_SmoothedDirectionalMovementMinus",
                                                                                            currentBar => ComputeSmoothedDirectionalMovementMinus(period),
                                                                                            isReady => _previousInput != null
                                                                                            );
        }