feat: add DMH (Ehlers Directional Movement with Hann) indicator

This commit is contained in:
Miha Kralj
2026-03-17 13:35:03 -07:00
parent 4552d8529d
commit 4fa29c04b7
15 changed files with 1419 additions and 0 deletions
+1
View File
@@ -360,6 +360,7 @@ HAS_AMAT = _bind("qtl_amat", [_dp, _dp, _dp, _ci, _ci, _ci])
HAS_AROON = _bind("qtl_aroon", [_dp, _dp, _ci, _ci, _dp])
HAS_AROONOSC = _bind("qtl_aroonosc", [_dp, _dp, _ci, _ci, _dp])
HAS_CHOP = _bind("qtl_chop", [_dp, _dp, _dp, _dp, _dp, _ci, _ci, _dp])
HAS_DMH = _bind("qtl_dmh", [_dp, _dp, _ci, _ci, _dp])
HAS_DMX = _bind("qtl_dmx", [_dp, _dp, _dp, _ci, _ci, _dp])
HAS_DX = _bind("qtl_dx", [_dp, _dp, _dp, _ci, _ci, _dp])
HAS_GHLA = _bind("qtl_ghla", [_dp, _dp, _dp, _dp, _ci, _ci])
+12
View File
@@ -15,6 +15,7 @@ __all__ = [
"aroon",
"aroonosc",
"chop",
"dmh",
"dmx",
"dx",
"minus_di",
@@ -122,6 +123,17 @@ def chop(open: object, high: object, low: object, close: object, volume: object,
return _wrap(dst, idx, f"CHOP_{period}", "dynamics", offset)
def dmh(high: object, low: object, period: int = 14, offset: int = 0, **kwargs) -> object:
"""Ehlers Directional Movement with Hann Windowing."""
period = int(kwargs.get("length", period))
offset = int(offset)
h, idx = _arr(high); l, _ = _arr(low)
n = len(h)
dst = _out(n)
_check(_lib.qtl_dmh(_ptr(h), _ptr(l), period, n, _ptr(dst)))
return _wrap(dst, idx, f"DMH_{period}", "dynamics", offset)
def dmx(high: object, low: object, close: object, period: int = 14, offset: int = 0, **kwargs) -> object:
"""Directional Movement Extended."""
period = int(kwargs.get("length", period))
+13
View File
@@ -527,6 +527,19 @@ public static unsafe partial class Exports
catch { return StatusCodes.QTL_ERR_INTERNAL; }
}
[UnmanagedCallersOnly(EntryPoint = "qtl_dmh")]
public static int QtlDmh(double* high, double* low, int period, int n, double* destination)
{
if (high == null || low == null || destination == null) return StatusCodes.QTL_ERR_NULL_PTR;
if (n <= 0) return StatusCodes.QTL_ERR_INVALID_LENGTH;
try
{
Dmh.Batch(Src(high, n), Src(low, n), period, Dst(destination, n));
return StatusCodes.QTL_OK;
}
catch { return StatusCodes.QTL_ERR_INTERNAL; }
}
[UnmanagedCallersOnly(EntryPoint = "qtl_dmx")]
public static int QtlDmx(double* high, double* low, double* close, int period, int n, double* destination)
{