1cd5d1d8da551cb15925aa007e956281c0239cb8
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
466faddd87 |
feat: Family 01 Moving Averages — ALMA / McGinley / FRAMA / VIDYA / JMA / Alligator / EVWMA (#39)
* 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
* feat(mcginley): add McGinley Dynamic moving average
John McGinley's self-adjusting moving average with the recurrence
MD + (price - MD) / (0.6 * period * (price / MD)^4). Speeds up when
price falls below the indicator and damps when price runs above the
indicator. Seeded with the simple average of the first period inputs.
Reference: McGinley, Technical Analysis of Stocks & Commodities, 1990.
Touchpoints:
- crates/wickra-core: mcginley_dynamic.rs + mod.rs + lib.rs re-export
- bindings/python: PyMcGinleyDynamic + __init__.py + test_new_indicators
+ test_known_values reference
- bindings/node: McGinleyDynamicNode (scalar macro) + index.d.ts/index.js
+ indicators.test.js factory + reference value
- bindings/wasm: wasm_scalar_indicator! macro
- fuzz: indicator_update target covers McGinleyDynamic(10)
- crates/wickra/benches: bench_scalar entry
- README + CHANGELOG: Moving Averages row + Unreleased entry
* feat(frama): add Fractal Adaptive Moving Average
Ehlers' FRAMA adapts its smoothing constant to the fractal dimension of
the recent window: tight tracking in trends, heavy smoothing in chop.
Uses the close-only variant where max/min over each window half drive
the dimension estimate. Period must be even (default 16).
Reference: Ehlers, Fractal Adaptive Moving Average, 2005.
Touchpoints:
- crates/wickra-core: frama.rs + mod.rs + lib.rs re-export
- bindings/python: PyFrama + __init__.py + test_new_indicators +
test_known_values reference (constant series + uptrend tracking)
- bindings/node: FramaNode (scalar macro) + index.d.ts/index.js +
indicators.test.js factory + reference value
- bindings/wasm: wasm_scalar_indicator! macro
- fuzz: indicator_update target covers Frama(16)
- crates/wickra/benches: bench_scalar entry
- README + CHANGELOG: Moving Averages row + Unreleased entry
* feat(vidya): add Variable Index Dynamic Average
Chande's VIDYA — an EMA whose alpha scales with |CMO(cmo_period)| / 100.
Strong directional momentum lifts the smoothing constant toward the
EMA-of-period rate; flat or choppy windows shrink it toward zero so
VIDYA coasts on its previous value. Two parameters: period (14) and
cmo_period (9). Reuses the existing wickra-core Cmo internally.
Reference: Chande, Stocks & Commodities, 1992.
Also fixes a silent gap from
|
||
|
|
b003321562 |
test(fuzz): cover every indicator, scalar and candle inputs (R9)
The fuzz suite previously covered only `Rsi(14)` and `Ema(20)` — 2 of 71 indicators, no OHLCV coverage at all. Audit finding R9 asked for ATR/ADX/Stochastic/PSAR as a minimum; this commit goes further and brings every indicator under fuzz. - `indicator_update` (rewritten): drives every scalar-input indicator through one streaming pass + one batch call per iteration. Covers SMA, EMA, WMA, RSI, DEMA, TEMA, HMA, ROC, TRIX, SMMA, TRIMA, ZLEMA, KAMA, T3, MOM, CMO, TSI, PMO, StochRSI, DPO, PPO, Coppock, StdDev, UlcerIndex, HistoricalVolatility, LinearRegression, LinRegSlope, LinRegAngle, VHF, ZScore, MACD, BollingerBands. A `drive` helper marked `#[inline(never)]` keeps each indicator on its own panic backtrace frame. - `indicator_update_candle` (new): chunks the fuzz `f64` stream into `[open, high, low, close, volume]` tuples, builds candles via `Candle::new` (skipping ones that fail OHLCV validation — that path is fuzz-tested separately), then drives every candle-input indicator through streaming + batch. Covers ATR, NATR, TrueRange, ChaikinVolatility, Keltner, Donchian, PSAR, SuperTrend, ChandelierExit, ChandeKrollStop, ATRTrailingStop, ADX, Aroon, AroonOscillator, Vortex, MassIndex, ChoppinessIndex, CCI, WilliamsR, AwesomeOscillator, AcceleratorOscillator, UltimateOscillator, BalanceOfPower, OBV, MFI, VWAP, RollingVWAP, VWMA, ADL, VPT, CMF, ChaikinOscillator, ForceIndex, EaseOfMovement, TypicalPrice, MedianPrice, WeightedClose, Stochastic. - `fuzz/Cargo.toml` registers the new target; `fuzz/README.md` describes both expanded targets. - A `fuzz-smoke` CI job runs each of the five targets for 30 s on every push and pull-request — enough to catch a regression in the harness without slowing CI to a crawl. Long fuzz campaigns belong on dedicated infrastructure with persistent corpora. |
||
|
|
78c31d1bed |
E16: add a cargo-fuzz harness
The repository had no fuzzing setup despite several natural targets — the CSV parser, the Binance envelope deserializer, and the stateful indicator/aggregator update paths. Add a fuzz/ cargo-fuzz crate (detached from the workspace via its own [workspace] table and the parent's exclude) with four targets: - csv_reader — CandleReader over arbitrary bytes - binance_envelope — RawWsEnvelope deserialization from arbitrary strings - indicator_update — RSI/EMA streaming + batch over arbitrary f64 series - tick_aggregator — TickAggregator over arbitrary tick triples Each target asserts the no-panic contract: malformed input must surface as an Err. fuzz/README.md documents running them (nightly + cargo-fuzz). |