feat(apo): add Absolute Price Oscillator

EMA(close, fast) - EMA(close, slow). Like MACD without the signal EMA.
Defaults to (fast = 12, slow = 26); fast must be strictly less than
slow.

Touchpoints: apo.rs + mod.rs + lib.rs re-export, PyApo + __init__.py
+ test_new_indicators SCALAR + test_known_values flat reference,
ApoNode + index.d.ts/index.js + indicators.test.js factory + reference,
WasmApo via scalar macro, scalar-fuzz target, README + CHANGELOG.
This commit is contained in:
kingchenc
2026-05-24 21:38:48 +02:00
parent e30b3c6b35
commit ec269d8aeb
11 changed files with 217 additions and 6 deletions
+4 -2
View File
@@ -15,8 +15,9 @@
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,
Apo, 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,
};
@@ -61,6 +62,7 @@ fuzz_target!(|data: Vec<f64>| {
drive(|| StochRsi::new(14, 14).unwrap(), &data);
drive(|| Dpo::new(14).unwrap(), &data);
drive(|| Ppo::new(12, 26).unwrap(), &data);
drive(|| Apo::new(12, 26).unwrap(), &data);
drive(|| Coppock::new(14, 11, 10).unwrap(), &data);
drive(|| StdDev::new(14).unwrap(), &data);
drive(|| UlcerIndex::new(14).unwrap(), &data);