From 4880fea075002692a554a415c605fcba5ac759a5 Mon Sep 17 00:00:00 2001 From: kingchenc Date: Fri, 22 May 2026 04:02:17 +0200 Subject: [PATCH] B5: complete the Python type stubs for all 25 indicators The .pyi shipped stubs for only 9 of the 25 exported classes, so with py.typed set, type checkers flagged DEMA, TEMA, HMA, KAMA, CCI, ROC, WilliamsR, ADX, MFI, TRIX, PSAR, Keltner, Donchian, VWAP, AwesomeOscillator and Aroon as missing. All 16 are now stubbed with signatures matching python/src/lib.rs (constructor defaults, update return types, batch array shapes, lifecycle methods). Verified: the stub set equals the 25 registered classes and mypy type-checks a script exercising every class with no issues. --- bindings/python/python/wickra/__init__.pyi | 199 +++++++++++++++++++++ 1 file changed, 199 insertions(+) diff --git a/bindings/python/python/wickra/__init__.pyi b/bindings/python/python/wickra/__init__.pyi index 4c3100f3..236b480f 100644 --- a/bindings/python/python/wickra/__init__.pyi +++ b/bindings/python/python/wickra/__init__.pyi @@ -135,3 +135,202 @@ class OBV: def warmup_period(self) -> int: ... @property def value(self) -> Optional[float]: ... + +class DEMA: + def __init__(self, period: int) -> None: ... + def update(self, value: float) -> Optional[float]: ... + def batch(self, prices: NDArray[np.float64]) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + @property + def period(self) -> int: ... + +class TEMA: + def __init__(self, period: int) -> None: ... + def update(self, value: float) -> Optional[float]: ... + def batch(self, prices: NDArray[np.float64]) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + @property + def period(self) -> int: ... + +class HMA: + def __init__(self, period: int) -> None: ... + def update(self, value: float) -> Optional[float]: ... + def batch(self, prices: NDArray[np.float64]) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + @property + def period(self) -> int: ... + +class KAMA: + def __init__(self, er_period: int = 10, fast: int = 2, slow: int = 30) -> None: ... + def update(self, value: float) -> Optional[float]: ... + def batch(self, prices: NDArray[np.float64]) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class CCI: + def __init__(self, period: int = 20) -> None: ... + def update(self, candle: CandleLike) -> Optional[float]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + close: NDArray[np.float64], + ) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + @property + def period(self) -> int: ... + +class ROC: + def __init__(self, period: int) -> None: ... + def update(self, value: float) -> Optional[float]: ... + def batch(self, prices: NDArray[np.float64]) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + @property + def period(self) -> int: ... + +class WilliamsR: + def __init__(self, period: int = 14) -> None: ... + def update(self, candle: CandleLike) -> Optional[float]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + close: NDArray[np.float64], + ) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class ADX: + def __init__(self, period: int = 14) -> None: ... + def update(self, candle: CandleLike) -> Optional[Tuple[float, float, float]]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + close: NDArray[np.float64], + ) -> NDArray[np.float64]: + """Returns shape ``(n, 3)`` with columns ``[plus_di, minus_di, adx]``.""" + ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class MFI: + def __init__(self, period: int = 14) -> None: ... + def update(self, candle: CandleLike) -> Optional[float]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + close: NDArray[np.float64], + volume: NDArray[np.float64], + ) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class TRIX: + def __init__(self, period: int) -> None: ... + def update(self, value: float) -> Optional[float]: ... + def batch(self, prices: NDArray[np.float64]) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class PSAR: + def __init__( + self, af_start: float = 0.02, af_step: float = 0.02, af_max: float = 0.20 + ) -> None: ... + def update(self, candle: CandleLike) -> Optional[float]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + close: NDArray[np.float64], + ) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class Keltner: + def __init__( + self, ema_period: int = 20, atr_period: int = 10, multiplier: float = 2.0 + ) -> None: ... + def update(self, candle: CandleLike) -> Optional[Tuple[float, float, float]]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + close: NDArray[np.float64], + ) -> NDArray[np.float64]: + """Returns shape ``(n, 3)`` with columns ``[upper, middle, lower]``.""" + ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class Donchian: + def __init__(self, period: int = 20) -> None: ... + def update(self, candle: CandleLike) -> Optional[Tuple[float, float, float]]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + ) -> NDArray[np.float64]: + """Returns shape ``(n, 3)`` with columns ``[upper, middle, lower]``.""" + ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class VWAP: + def __init__(self) -> None: ... + def update(self, candle: CandleLike) -> Optional[float]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + close: NDArray[np.float64], + volume: NDArray[np.float64], + ) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class AwesomeOscillator: + def __init__(self, fast: int = 5, slow: int = 34) -> None: ... + def update(self, candle: CandleLike) -> Optional[float]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + ) -> NDArray[np.float64]: ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ... + +class Aroon: + def __init__(self, period: int = 14) -> None: ... + def update(self, candle: CandleLike) -> Optional[Tuple[float, float]]: ... + def batch( + self, + high: NDArray[np.float64], + low: NDArray[np.float64], + ) -> NDArray[np.float64]: + """Returns shape ``(n, 2)`` with columns ``[up, down]``.""" + ... + def reset(self) -> None: ... + def is_ready(self) -> bool: ... + def warmup_period(self) -> int: ...