32 private readonly
int _period;
45 public override bool IsReady => _averageDirectionalIndex.IsReady;
73 : this($
"ADX({period})", period)
89 isReady => _previousInput !=
null
93 ComputePositiveDirectionalMovement,
94 isReady => _previousInput !=
null
98 ComputeNegativeDirectionalMovement,
99 isReady => _previousInput !=
null
106 if (_smoothedTrueRange != 0 && _smoothedDirectionalMovementPlus.IsReady)
108 return 100m * _smoothedDirectionalMovementPlus.Current.Value / _smoothedTrueRange.Current.Value;
112 positiveDirectionalIndex => _smoothedDirectionalMovementPlus.IsReady,
115 _directionalMovementPlus.Reset();
124 if (_smoothedTrueRange != 0 && _smoothedDirectionalMovementMinus.IsReady)
126 return 100m * _smoothedDirectionalMovementMinus.Current.Value / _smoothedTrueRange.Current.Value;
130 negativeDirectionalIndex => _smoothedDirectionalMovementMinus.IsReady,
133 _directionalMovementMinus.Reset();
142 var value = Samples > _period + 1 ? _smoothedTrueRange.Current.Value / _period : 0m;
143 return _smoothedTrueRange.Current.Value + _trueRange.Current.Value - value;
145 isReady => Samples > period
152 var value = Samples > _period + 1 ? _smoothedDirectionalMovementPlus.Current.Value / _period : 0m;
153 return _smoothedDirectionalMovementPlus.Current.Value + _directionalMovementPlus.Current.Value - value;
155 isReady => Samples > period
162 var value = Samples > _period + 1 ? _smoothedDirectionalMovementMinus.Current.Value / _period : 0m;
163 return _smoothedDirectionalMovementMinus.Current.Value + _directionalMovementMinus.Current.Value - value;
165 isReady => Samples > period
178 if (_previousInput ==
null)
return 0m;
180 var range1 = input.
High - input.
Low;
181 var range2 = Math.Abs(input.
High - _previousInput.
Close);
182 var range3 = Math.Abs(input.
Low - _previousInput.
Close);
184 return Math.Max(range1, Math.Max(range2, range3));
192 private decimal ComputePositiveDirectionalMovement(
IBaseDataBar input)
194 if (_previousInput !=
null &&
196 input.
High - _previousInput.
High >= _previousInput.
Low - input.
Low)
198 return input.
High - _previousInput.
High;
208 private decimal ComputeNegativeDirectionalMovement(
IBaseDataBar input)
210 if (_previousInput !=
null &&
211 _previousInput.
Low > input.
Low &&
212 _previousInput.
Low - input.
Low > input.
High - _previousInput.
High)
214 return _previousInput.
Low - input.
Low;
226 _trueRange.Update(input);
227 _directionalMovementPlus.Update(input);
228 _directionalMovementMinus.Update(input);
229 _smoothedTrueRange.Update(Current);
230 _smoothedDirectionalMovementPlus.Update(Current);
231 _smoothedDirectionalMovementMinus.Update(Current);
232 _previousInput = input;
239 if (sum == 0)
return 50m;
241 _averageDirectionalIndex.Update(input.
EndTime, 100m * diff / sum);
243 return _averageDirectionalIndex.Current.Value;
252 _previousInput =
null;
254 _directionalMovementPlus.Reset();
255 _directionalMovementMinus.Reset();
256 _smoothedTrueRange.Reset();
257 _smoothedDirectionalMovementPlus.Reset();
258 _smoothedDirectionalMovementMinus.Reset();
259 _averageDirectionalIndex.Reset();