feat(dynamics): add PlusDI, MinusDI, PlusDM, MinusDM indicators

Complete thin Dx-composition wrapper indicators with full test coverage:

- PlusDi/MinusDi: Directional Indicator wrappers (DiPlus/DiMinus from Dx)
- PlusDm/MinusDm: Directional Movement wrappers (DmPlus/DmMinus from Dx)
- Individual validation tests per indicator directory (TALib, Skender, bounds)
- Combined unit tests (DiDm.Tests.cs) and validation tests (DiDm.Validation.Tests.cs)
- Quantower wrappers + tests for all 4 indicators
- PineScript v6 implementations with compensated RMA
- Normalized .md documentation for all indicators and categories
- 182 tests passing, 0 failures
This commit is contained in:
Miha Kralj
2026-03-11 20:21:52 -07:00
parent 56b86bebfb
commit 33d20f2a18
437 changed files with 4589 additions and 2792 deletions
+2 -41
View File
@@ -1,5 +1,7 @@
# DMX: Directional Movement Index (Jurik)
> *Jurik's directional movement applies adaptive smoothing to DI lines, reducing whipsaws in the classic DMI framework.*
| Property | Value |
| ---------------- | -------------------------------- |
| **Category** | Dynamic |
@@ -70,47 +72,6 @@ Positive values indicate bullish directional dominance; negative values indicate
|--------|-----------|---------|------------|
| $N$ | period | 14 | $N \geq 2$ |
### Pseudo-code
```
Initialize:
jmaPlusDM = new JMA(period)
jmaMinusDM = new JMA(period)
jmaTR = new JMA(period)
prevHigh = prevLow = prevClose = NaN
On each bar (high, low, close, isNew):
if !isNew: restore previous state
// Wilder's directional movement decomposition
TR = max(high - low, |high - prevClose|, |low - prevClose|)
upMove = high - prevHigh
downMove = prevLow - low
+DM = (upMove > downMove AND upMove > 0) ? upMove : 0
-DM = (downMove > upMove AND downMove > 0) ? downMove : 0
// Jurik smoothing (replaces Wilder's RMA)
smoothPlusDM = jmaPlusDM.Update(+DM)
smoothMinusDM = jmaMinusDM.Update(-DM)
smoothTR = jmaTR.Update(TR)
// Directional indicators
if smoothTR > 0:
DI_plus = 100 × smoothPlusDM / smoothTR
DI_minus = 100 × smoothMinusDM / smoothTR
else:
DI_plus = DI_minus = 0
DMX = DI_plus - DI_minus
prevHigh = high
prevLow = low
prevClose = close
output = DMX
```
### DMX vs DMI Comparison
| Property | DMI (Wilder) | DMX (Jurik) |