feat(alma): add Arnaud Legoux Moving Average

Gaussian-weighted moving average with configurable centre (offset in
[0, 1]) and kernel width (sigma > 0). Pre-computes normalised weights
at construction so each update is a single rolling window dot product.

Reference: Arnaud Legoux and Dimitrios Kouzis-Loukas, 2009.

Touchpoints:
- crates/wickra-core: alma.rs + mod.rs + lib.rs re-export
- bindings/python: PyAlma + __init__.py + test_new_indicators +
  test_known_values reference
- bindings/node: AlmaNode + index.d.ts/index.js + indicators.test.js
  factory + reference value
- bindings/wasm: wasm_scalar_indicator! macro
- fuzz: indicator_update target covers ALMA(9, 0.85, 6.0)
- crates/wickra/benches: bench_scalar entry
- README + CHANGELOG: Moving Averages row + Unreleased entry
This commit is contained in:
kingchenc
2026-05-24 12:21:18 +02:00
parent e30b3c6b35
commit 2454d7cf92
15 changed files with 494 additions and 9 deletions
+5 -4
View File
@@ -15,10 +15,10 @@
use libfuzzer_sys::fuzz_target;
use wickra_core::{
BatchExt, BollingerBands, Cmo, Coppock, Dema, Dpo, Ema, HistoricalVolatility, Hma, Indicator,
Kama, LinRegAngle, LinRegSlope, LinearRegression, MacdIndicator, Mom, Pmo, Ppo, Roc, Rsi, Sma,
Smma, StdDev, StochRsi, T3, Tema, Trima, Trix, Tsi, UlcerIndex, VerticalHorizontalFilter, Wma,
ZScore, Zlema,
Alma, BatchExt, BollingerBands, Cmo, Coppock, Dema, Dpo, Ema, HistoricalVolatility, Hma,
Indicator, Kama, LinRegAngle, LinRegSlope, LinearRegression, MacdIndicator, Mom, Pmo, Ppo, Roc,
Rsi, Sma, Smma, StdDev, StochRsi, T3, Tema, Trima, Trix, Tsi, UlcerIndex,
VerticalHorizontalFilter, Wma, ZScore, Zlema,
};
/// Drive a single streaming + batch run through one scalar indicator. Marked
@@ -53,6 +53,7 @@ fuzz_target!(|data: Vec<f64>| {
drive(|| Trima::new(14).unwrap(), &data);
drive(|| Zlema::new(14).unwrap(), &data);
drive(|| Kama::new(10, 2, 30).unwrap(), &data);
drive(|| Alma::new(9, 0.85, 6.0).unwrap(), &data);
drive(|| T3::new(14, 0.7).unwrap(), &data);
drive(|| Mom::new(14).unwrap(), &data);
drive(|| Cmo::new(14).unwrap(), &data);