Files
Miha Kralj 33d20f2a18 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
2026-03-11 20:21:52 -07:00

56 lines
1.8 KiB
Plaintext

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Minus Directional Indicator (-DI)", "-DI", overlay=false)
//@function Calculates -DI using Wilder's smoothing with compensated RMA
//@param period Number of bars used in the calculation
//@returns -DI value (0-100)
//@optimized Uses Wilder's smoothing (RMA) with warmup compensation for accurate values from bar 1
minusdi(simple int period) =>
if period <= 0
runtime.error("Period must be greater than 0")
float alpha = 1.0 / period
float beta = 1.0 - alpha
float tr = 0.0
float minus_dm = 0.0
if na(close[1])
tr := high - low
else
tr := math.max(high - low, math.max(math.abs(high - close[1]), math.abs(low - close[1])))
float upMove = high - high[1]
float downMove = low[1] - low
if downMove > upMove and downMove > 0
minus_dm := downMove
var bool warmup = true
var float e = 1.0
var float tr_ema = 0.0
var float tr_result = tr
var float minus_dm_ema = 0.0
var float minus_dm_result = minus_dm
tr_ema := alpha * (tr - tr_ema) + tr_ema
minus_dm_ema := alpha * (minus_dm - minus_dm_ema) + minus_dm_ema
if warmup
e *= beta
float c = 1.0 / (1.0 - e)
tr_result := c * tr_ema
minus_dm_result := c * minus_dm_ema
warmup := e > 1e-10
else
tr_result := tr_ema
minus_dm_result := minus_dm_ema
float minus_di = tr_result != 0.0 ? 100.0 * minus_dm_result / tr_result : 0.0
minus_di
// ---------- Main loop ----------
// Inputs
i_period = input.int(14, "Period", minval=1, tooltip="Number of bars used in the calculation")
// Calculation
minus_di = minusdi(i_period)
// Plot
plot(minus_di, "-DI", color=color.red, linewidth=2)
hline(25, "Threshold", color=color.gray, linestyle=hline.style_dashed)